home *** CD-ROM | disk | FTP | other *** search
- ; RN.ASM
- ; 'Copyright 1987 Ziff-Davis Publishing Co.'
- ; 'Michael J. Mefford$'
- ; Format RN [d:][directory]
- ;
- ;Michael J. Mefford 1987/No. 16 (Utilities)
- ;
- ;This is a modified version of PC Magazines RN Utility
- ;It has Been modified for some special batch tasks.
- ;Several new parameters have been added.
- ;
- ;Purpose:
- ;Select, create, rename, delete or backup selected directory.
- ;
- ;
- ;Format:
- ;RN [d:][\directory 1] [d:][\directory 2] [/E][/S][/D][/T][/O]
- ; [/M1] [/M2] [/M3] [/M4]
- ;
- ;Directory 1 - RN will display this directory and any subdirectories.
- ;Directory 2 - Passed to CO.
- ;
- ;
- ;/E - Passed to CO.
- ;/S - Passed to CO.
- ;/D - Passed to CO.
- ;/T - Passed to CO.
- ;/O - Passed to CO.
- ;/M1 - Exit when return pressed, normally the program goes to CO.
- ;/M2 - Don't use Directory 1 parameter pass to CO.
- ;/M3 - Passed to CO.
- ;/M4 - Passed to CO.
- ;
- ;Program Functions:
- ;
- ; ╔═════════════════════════════╗
- ; ║ PC Magazine RN.COM ║
- ; ╟─────────────────────────────╢
- ; ║ Enter ─┘ to Select Directry║
- ; ║ F2 ^Exit to DOS ║
- ; ║ ║
- ; ║ F4 ^File Maintenance ║
- ; ║ F5 ^Rename Directory ║
- ; ║ F6 Delete dir & all files ║
- ; ║ F7 ^Make a new Directory ║
- ; ║ F8 ^Change Backup/Rest Parm║
- ; ║ F9 ^Backup Directory ║
- ; ║ F10 Restore Directory ║
- ; ║ Backup/Restore Parameters ║
- ; ║ ^Dr=A: ^Path=*.* ║
- ; ║ ^Options=/S ║
- ; ║ Esc to Cancel Program ║
- ; ╚═════════════════════════════╝
- ; Use: PgUp PgDn
- ; ^PgUp ^PgDn Home End
- ;
- ;
- ;Modified by Bob Hunt 414-287-3308
-
- CODE SEGMENT ;*************************
- ASSUME CS:CODE,DS:CODE ;* *
- ORG 100H ;* REMEMBER TO EXE2BIN *
- ;* *
- START: JMP BEGINNING ;*************************
-
- ;; DATA AREA
- ; ---------
- USE_DIRECTORY DB 12 DUP (32),0 ;DISPLAY ONLY THIS DIRECTORY
- SAVE_LAST_SLASH DW 0
- IS_THERE_FILE DB 0
- USE_DIR_EQ DB ? ;CUR = USE_DIRECTORY
- SAVE_SORT DB '/N' ;SAVE SORT PARM FOR CO OR DR
- TEMPUS_RETCODE DB 0 ;return code
- MENU_TYPE DB 0 ; MENU TYPE FROM PARMS
- INSTALL_MSG DB 'RN sucessfully installed',13,10
- COPYRIGHT DB 'Copyright 1987 Ziff-Davis Publishing Co.',13,10
- PROGRAMMER DB 'Michael J. Mefford$',1AH
- NO_FREE DB 'Too many resident programs$'
- REQUIRES DB 'Requires DOS 2.x$'
- NOT_ENOUGH DB 'Requires 128K free RAM$'
- UNKNOWN DB 'Drive not supported$'
- HEADING DB 'Select a Directory from drive ',0
- DIR_MSG DB ' directories',0
- FILE_COUNT DB ' files in ',0
- PATH_ERROR DB 'PROGRAM CO.COM NOT FOUND',0
- BACKUP_USES DB 'Backup will use ',0
- BACKUP_USES_1_2MEG DB ' 1.2Meg (Red) disks',0
- BACKUP_USES_1_4MEG DB ' 1.4Meg(3 1/2") disks',0
- BACKUP_USES_360K DB ' 360k disks',0
- FORMAT_MSG DB 'Format disketts (Y) or (N)?',0
- USING DB ' using ',0
- LOADING DB 'Loading and sorting directories',13,10,0
- RENAME_MSG DB 'Enter new name for ',0
- PATH_LENGTH DB 'Path length is now ',0
- DB '. Maximum is 63.',0
- MKDIR_MSG1 DB 'We suggest using your LAST NAME ',0
- MKDIR_MSG DB 'Enter new subdirectory Name for ',0
- RMDIR_MSG0 DB 'Directory Deleted 0 files in directory',0
- RMDIR_MSG DB 'Warning: All files will be lost. ',0
- DB 'Do you still wish to remove it? Y/N ',0
- RMDIR_MSG2 DB 'Are you sure you want to DELETE ',0
- DB 'EVERYTHING in this directory???? Y/N ',0
- HIDE_MSG DB 'H to hide or U to unhide ',0
- READ_ONLY_MSG DB 'R to mark read-only U to undo read-only',0
- ARCHIVE_MSG DB 'S to set R to reset archive bit',0
- HAVE_BEEN DB 'have been marked ',0
- DB 'not to be BACKUPed.',0
- READ_MSG DB 'not read-only.',0
- BRDRIVE_MSG DB 'Enter disk drive letter ',0
- BRPATH_MSG DB 'Enter DOS Path ',0
- BROPTIONS_MSG DB 'Enter Backup/Restore Options ',0
- BS DB 8,32,8,0
-
- DATA_INT DB 0
- DATA_SEGMENT DW ?
-
- DOS_VERSION DB ?
- ROOT DB '\ (ROOT)'
- ROOT_DIR DB '\',0
- DOT_DOT DB '..',0
- STAR_DOT_STAR DB '*.*',0
- CLUST_BYTES_1_2MEG DW 512
- CLUSTERS_1_2MEG DW 2371-1
- CLUST_COUNT_1_2MEG DW ?
- T_CLUST_COUNT_1_2MEG DW ?
- DISKS_1_2MEG DW ?
- CLUST_BYTES_1_4MEG DW 512
- CLUSTERS_1_4MEG DW 2847-1
- CLUST_COUNT_1_4MEG DW ?
- T_CLUST_COUNT_1_4MEG DW ?
- DISKS_1_4MEG DW ?
- CLUST_BYTES_360K DW 1024
- CLUSTERS_360K DW 354-1
- CLUST_COUNT_360K DW ?
- T_CLUST_COUNT_360K DW ?
- DISKS_360K DW ?
- DEFAULT_DIR DB 64 DUP (00),0 ;CURRENT DIRECTORY WHEN PROG ENTERED
- DEFAULT_DRIVE DB ?
- DRIVE DB ?
- ROOT_SECTORS DW ?
- CLUST_RECORDS DW ?
- CLUST_SECTORS DW ?
- CLUST_BYTES DW ?
- CLUST_COUNT DW ?
- LAST_CLUSTER DW ?
- LAST_ENTRY DW ?
- END_OFFSET DW ?
- AT_LAST_LINE DB 0
- STRIP_MASK DB ?
- ADD_MASK DB ?
-
- STATUS_REG DW ?
- VIDEO_SEG DW 0B000H
- NORMAL DB 07H
- INVERSE DB 70H
- BAR_ATTRIBUTE DB 70H
- ATTR_TREE DB 07H
- ATTR_MENU DB 07H
- ATTR_TEXT DB 07H
- ATTR_MSGS DB 07H
- CURSOR_TYPE DW ?
- CUR_OFFSET_SAVE DW ? ; SAVE CURRENT OFFSET
- CUR_OFFSET DW DIRECTORIES
- CUR_RECORD DW ?
- CUR_LEVEL DW ? ;SAVE CURRENT LEVEL
- CUR_LEVEL_SAVE DW ? ;SAVE LEVEL
- PAGE_START EQU 323
- PAGE_END DW 21*160+PAGE_START
- LINE DW PAGE_START
- LINE_SAVE DW PAGE_START ; SAVE CURRENT LINE
- DIR_COUNT DW 1
- COUNT DW ?
- COUNT_SAVE DW ?
- BAR_START DW PAGE_START
- BAR_LENGTH DW 8
- SEARCH_COUNT DW ?
- DIR_NAME DW ?
-
- SAVE_DS_PATH DW 0
- SAVE_SI_PATH DW 0
- PATH DB 0,'PATH='
- PATH_FOR_PGM DB 76 DUP (00),0 ;STORE PATH= FOR EXECUTE
- COMSPEC DB 'COMSPEC='
- PARA_BR DB 60 DUP (00)
- PARA_BACKUP DB '/C BACKUP ',0
- PARA_ADD DW ' '
- PARA_RESTORE DB '/C RESTORE ',0
- PARA_FORMAT DB '/C FORMAT ',0
- PARAMETER DB '/C CO /M4 /N ',0
- PARAMETER_DOS DB '/C DIR ',0
- PARM_SAVE_LGTH DB 0
- PARM_SAVE DB 101 DUP (0D)
- LOAD_NAME_CO DB '\CO.COM'
- DB 0
-
- ENVIRONMENT DW ?
- COM_LINE_PTR DD OFFSET PARAMETER
- STACK_SEG DW ?
- STACK_PTR DW ?
-
- DIR_RECORD EQU 40
- DATA_RECORD EQU 20
-
- ROOT_DIRECTORY EQU 0
- FAT EQU ROOT_DIRECTORY
- WORKSPACE EQU 65535-16384
-
- K_ESC EQU 1
- K_MINUS EQU 12
- K_PLUS EQU 13
- K_BACKSPACE EQU 14
- K_E EQU 18
- K_R EQU 18
- K_T EQU 20
- K_Y EQU 21
- K_O EQU 24
- K_P EQU 25
- K_ENTER EQU 28
- K_S EQU 31
- K_D EQU 32
- K_F EQU 33
- K_C EQU 46
- K_V EQU 47
- K_B EQU 48
- K_N EQU 49
- K_M EQU 50
- K_F1 EQU 59
- K_F2 EQU 60
- K_F3 EQU 61
- K_F4 EQU 62
- K_F5 EQU 63
- K_F6 EQU 64
- K_F7 EQU 65
- K_F8 EQU 66
- K_F9 EQU 67
- K_F10 EQU 68
- K_NUM_LOCK EQU 69
- K_SCROLL_LOCK EQU 70
- K_HOME EQU 71
- K_UP_ARROW EQU 72
- K_PGUP EQU 73
- K_PRTSC EQU 55
- KN_MINUS EQU 74
- K_LEFT_ARROW EQU 75
- K_RIGHT_ARROW EQU 77
- KN_PLUS EQU 78
- K_END EQU 79
- K_DOWN_ARROW EQU 80
- K_PGDN EQU 81
- K_INS EQU 82
- K_DEL EQU 83
- K_LEFT_SHIFT EQU 42
- K_RIGHT_SHIFT EQU 36
- K_TAB EQU 15
- K_CTRL EQU 29
- K_ALT EQU 56
- K_SPACE EQU 57
- K_CAPS_LOCK EQU 58
- K_CTRL_PGDN EQU 118
- K_CTRL_PGUP EQU 132
-
- DEFAULT_MENU_NO DB 2 ;DEFAULT IS SMALL MENU
- DEFAULT_MENU DB 2 ;DEFAULT IS SMALL MENU
-
- DISPATCH_KEY DB K_ESC,
- DB K_ENTER
- DB K_F3
- DB K_F1, K_F2, K_F7
- DB K_E
- DB K_F5, K_F6, K_F8, K_F4
- DB K_F9
- DB K_B
- DB K_F10, K_HOME, K_UP_ARROW, K_PGUP
- DB K_END,K_DOWN_ARROW,K_PGDN, K_CTRL_PGDN, K_CTRL_PGUP
- DB K_F, K_R, K_C, K_M
- DB K_D, K_P, K_O
- DISPATCH_CNT EQU $ - DISPATCH_KEY
-
- DISPATCH_TABLE DW ESC_EXIT
- MENU_1 DW SELECT_DIR
- DW NO_OP
- DW HELP, EXIT_DOS, MKDIR
- DW EXIT_DOS
- DW RENAME, RMDIR, B_R_OPTIONS, CO
- DW BACKUP
- DW BACKUP
- DW RESTORE, HOME_BAR, UP_ARROW, PG_UP
- DW END_BAR, DN_ARROW, PG_DN, BOTTOM_BAR, TOP_BAR
- DW CO, RENAME, B_R_OPTIONS, MKDIR
- DW BRDRIVE, BRPATH, BROPTIONS
- DISPATCH_END EQU $ - 2
-
- ;----------------------FW SMALL MENU -------------------------------
- DISPATCH_KEY2 DB K_ESC,
- DB K_ENTER
- DB K_F2
- DB K_F4
- DB K_HOME,K_UP_ARROW, K_PGUP
- DB K_END, K_DOWN_ARROW,K_PGDN, K_CTRL_PGDN, K_CTRL_PGUP
- DISPATCH_CNT2 EQU $ - DISPATCH_KEY2
-
- DISPATCH_TABLE2 DW ESC_EXIT
- MENU_2 DW SELECT_DIR
- DW NEW_USER
- DW NEW_MENU
- DW HOME_BAR, UP_ARROW, PG_UP
- DW END_BAR, DN_ARROW, PG_DN, BOTTOM_BAR, TOP_BAR
- DISPATCH_END2 EQU $ - 2
- ;-------------------------------------------------------------------
-
- MENU_WIDTH EQU 31
- MENU_LGTH EQU 20
- MENU LABEL BYTE
- DB 201,29 DUP (205),187,
- DB 186,' PC Magazine RN.COM ',186
- DB 199,29 DUP (196),182
- DB 186,' Enter ',17,196,217,' to Select Directry',186
- DB 186,' F2 ^Exit to DOS ',186
- DB 186,' ',186
- DB 186,' F4 ^File Maintenance ',186
- ROPTION DB 186,' F5 ^Rename Directory ',186
- RLINE EQU ROPTION+1
- DB 186,' F6 Delete dir & all files ',186
- DB 186,' F7 ^Make a new Directory ',186
- DB 186,' F8 ^Change Backup/Rest Parm',186
- DB 186,' F9 ^Backup Directory ',186
- DB 186,' F10 Restore Directory ',186
- DB 186,' Backup/Restore Parameters ',186
- CDRIVE DB 186,' ^Dr=A: ^Path=*.* ',186
- ODRIVE EQU CDRIVE+7
- OPATH EQU CDRIVE+16
- COPTIONS DB 186,' ^Options=/S ',186
- OOPTIONS EQU COPTIONS+12
- DB 186,' Esc to Cancel Program ',186
- DB 200,29 DUP (205),188,
- DB ' Use: ',24,32,25,' PgUp PgDn '
- DB ' ^PgUp ^PgDn Home End '
-
- MENU2 LABEL BYTE
- DB 201,29 DUP (205),187,
- DB 186,' PC Magazine RN.COM ',186
- DB 199,29 DUP (196),182
- DB 186,'To SELECT, use the ',24,' ',25,' cursor',186
- DB 186,' keys or the mouse to move ',186
- DB 186,' the HIGHLIGHTED box to the ',186
- DB 186,' Directory you wish, press ',186
- DB 186,' the left mouse botton or the',186
- DB 186,'Enter ',17,196,217,' key. ',186
- DB 186,' ',186
- DB 186,' F2 NEW USERS press F2 Key ',186
- DB 186,' to Create Data Directory',186
- DB 186,' ',186
- DB 186,' F4 Maintenance functions ',186
- DB 186,' for Directories & Files.',186
- DB 186,' ',186
- DB 186,' Esc to Cancel Program ',186
- DB 200,29 DUP (205),188,
- DB ' Use: ',24,32,25,' PgUp PgDn '
- DB ' ^PgUp ^PgDn Home End '
- ; DB 201,20 DUP (205),187,186,' PC Magazine RN.COM ',186
- ; DB 186,' (C) Copr. 1987 ZD ',186,186,' Michael J. Mefford ',186
- ; DB 199,20 DUP (196),182,186,' F1 ChDir (or ',17,196,217,')',186
- ;DB 186,' F2 Rename ',186,186,' F3 MkDir ',186
- ;DB 186,' F4 RmDir ',186,186,' F5 Hide/Unhide ',186
- ;DB 186,' F6 Do/Undo R-O ',186,186,' F7 Set/Reset Arc ',186
- ;DB 186,' F8 Reread ',186,186,' F9 File count ',186
- ;DB 186,' F10 DR ',186,186,' Esc to End ',186
- ;DB 200,20 DUP (205),188,' Use: ',24,32,25,' PgUp PgDn '
- ;DB ' ^PgUp ^PgDn Home End '
-
- ;---------------------------------------------------------------------;
- ; Store our data segment. We will be writing directly to the screen ;
- ; buffer so we need the display card address and the status register. ;
- ;---------------------------------------------------------------------;
-
- ; CODE AREA
- ; ---------
- BEGINNING: CLD ;String moves in forward direction.
- PUSH DS
- POP DATA_SEGMENT ;Store our data segment.
- MOV AX,3301H ;Turn Control Break off.
- MOV DL,0
- INT 21H
-
- MOV AX,40H ;Point to the ROM BIOS data area
- MOV DS,AX ; and get base address of active
- MOV AX,DS:[63H] ; display card.
- ADD AX,6 ;Add six to get status register
- PUSH CS ;Done there, so restore data segment.
- POP DS
- MOV STATUS_REG,AX ;Store status register.
- CMP AX,3BAH ;Status port of MONO card is 3BAh.
- JZ MONO ;If that's what we got, it's MONO
- MOV VIDEO_SEG,0B800H ; else COLOR so add 800h.
- XOR BH,BH ;Get current attribute
- MOV AH,8 ; of display page zero.
- INT 10H
- MOV NORMAL,AH ;Store it.
- MOV AH,07
- XOR AH,1110111xB ;Flip color bits.
- MOV INVERSE,AH ;Save it.
- MOV BAR_ATTRIBUTE,AH
- MOV ATTR_TREE,14 ;Store it.
- MOV ATTR_MENU,03 ;Store it.
- MOV ATTR_TEXT,02 ;Store it.
- MOV ATTR_MSGS,04 ;Store it.
- MONO: XOR BH,BH
- MOV AH,3 ;Retrieve cursor type.
- INT 10H
- MOV CURSOR_TYPE,CX ;And save it.
- CALL CURSOR_OFF
-
- ;---------------------------------------------;
- ; Check DOS version and allocate 128K memory. ;
- ;---------------------------------------------;
-
- MOV AH,30H ;Get DOS version.
- INT 21H
- MOV DOS_VERSION,AL ;And save.
- CMP AL,2 ;Is it 2.x or above?
- JAE CONTINUE ;If yes, continue.
-
- MOV DX,OFFSET REQUIRES ;Else, exit with message.
- QUIT: JMP MSG_EXIT
-
- CONTINUE: CMP AL,3 ;Is it DOS 3.x or above?
- JAE RENAME_OK ;If yes continue.
- MOV RLINE,'N' ;Else mark rename function
- MOV RLINE+1,'/' ; Not/Available.
- MOV RLINE+2,'A'
- RENAME_OK: MOV AH,49H ;Return our memory segment.
- INT 21H
- MOV BX,2000H ;Request 128K.
- MOV AH,4AH
- INT 21H
- MOV DX,OFFSET NOT_ENOUGH ;If not available, exit
- JC QUIT ; with message.
-
- MOV AH,19H ;Get default drive and save.
- INT 21H
- MOV DEFAULT_DRIVE,AL
-
- MOV SI,OFFSET DEFAULT_DIR ;Point to default directory.
- MOV BYTE PTR [SI],'\' ;DOS fails to include starting "\".
- INC SI ;Point to first level.
- MOV DL,DEFAULT_DRIVE ;Retrieve drive.
- INC DL ;Convert to DOS format.
- MOV AH,47H ;Retrieve current directory.
- INT 21H
- CALL CAPITALIZE ;Capitalize it.
-
- ;-----------------------------------------------------;
- ; Check for drive request. Retrieve Disk Block info. ;
- ;-----------------------------------------------------;
-
- MOV AL,DS:[5CH] ;Get drive request.
- MOV BL,AL ;Save it.
- DEC AL ;Adjust.
- OR BL,BL ;If it was zero, no request.
- JNZ STORE_DRIVE
-
- MOV AH,19H ;Then get default drive.
- INT 21H
- STORE_DRIVE: MOV DRIVE,AL ;Store it.
- MOV DL,AL
- MOV AH,0EH ;Change drive to requested.
- INT 21H
-
- MOV DL,DRIVE ;Retrieve drive.
- INC DL ;Adjust.
- MOV AH,32H ;Retrieve Disk Block.
- INT 21H
- OR AL,AL ;Does disk request exist?
- JZ EXISTS
- JMP DISK_EXIT ;If no, exit with message.
- EXISTS: MOV SI,BX ;Store Disk Block.
- MOV DI,OFFSET DISK_BLOCK
- MOV CX,18
- REP MOVSB
- PUSH CS ;Restore data segment.
- POP DS
-
- CMP DRIVE,1 ;Is drive request A: or B:?
- JA CK_FREE
- JMP READ ;If yes, automatic read.
-
- ;---------------------------------------------------;
- ; Check to see if our database has been installed. ;
- ;---------------------------------------------------;
-
- CK_FREE: MOV AL,60H - 1 ;Available vectors are 60H - 67H.
- FREE_USER_INT: INC AL
- MOV AH,35H ;Get vector address.
- INT 21H
- CMP BX,0 ;Is offset being used?
- JNZ CK_SIGNATURE ;If yes, see if it's us.
- MOV DX,ES
- CMP DX,0 ;Is segment being used?
- JNZ CK_SIGNATURE ;If yes, see if it's us.
- MOV DATA_INT,AL ;If available, save INT number.
- JMP SHORT NEXT_USER ;Check all 7.
-
- CK_SIGNATURE: MOV DI,BX ;See if INT has our signature.
- MOV SI,OFFSET INSTALL_MSG
- MOV CX,30/2
- REPZ CMPSW
- JNZ NEXT_USER
- JMP CK_SUBST ;If yes, already installed.
-
- NEXT_USER: CMP AL,67H ;Have we checked all 7?
- JNZ FREE_USER_INT ;If no, next one.
- CMP DATA_INT,0 ;Did we find one that was free?
- JNZ CK_SWITCH
- MOV DX,OFFSET NO_FREE ;If no, exit with message.
- JMP ERROR_EXIT
-
- CK_SWITCH: PUSH ES ;Restore data segment.
- MOV ES,DS
- ;------------------------FW-------------------------------------------
- MOV SI,80H ;See if request to install.
- XOR AX,AX
- LODSB
- MOV CX,AX
- MOV DI,OFFSET PARM_SAVE ;SET TO TYPE MENU STORE
- REPNZ MOVSB
- MOV BYTE PTR [DI]," "
- INC DI
- MOV BYTE PTR [DI],"-"
- INC DI
- MOV BYTE PTR [DI],0D ;PUT IN CARRIAGE RETURN
- MOV AX,DI ;NEW PARM LGHT
- SUB AX,OFFSET PARM_SAVE ;SET TO TYPE MENU STORE
- MOV PARM_SAVE_LGTH,AL ;SAVE LGTH
- ;---------------------------------------------------------------------
- MOV SI,80H ;See if request to install.
- LODSB
- CMP AL,0 ;If no parameters, read data.
- JNE NEXT_SWITCH
- JMP CK_SWITCH_END
- NEXT_SWITCH: LODSB
- CMP AL,0 ;If 00 END
- JNE CK_CR_RETURN
- JMP CK_SWITCH_END
- CK_CR_RETURN: CMP AL,13 ;End of parameters?
- JNE CK_SLASH
- JMP CK_SWITCH_END ;If yes, read data.
- CK_SLASH: CMP AL,'\' ;DIRECTORY?
- JZ SAVE_DIR
- CMP AL,'/' ;Switch character?
- JNZ NEXT_SWITCH
- MOV BL,BYTE PTR [SI] ;LOAD CHAR
- AND BL,5FH ;CAPITALIZE
- CMP BL,'M' ;=M?
- JE MENU_CHK ;YES
- MOV DI,OFFSET SAVE_SORT ;SET TO BEGIN OF RECORD
- STOSB
- LODSB
- CMP AL,13 ;End of parameters?
- JZ CK_SWITCH_END ;If yes, read data.
- STOSB
- JMP NEXT_SWITCH
- ;----------------------FW CHANGE-------------------------------------
- MENU_CHK: LODSB ;LOAD M
- LODSB ;LOAD MENU CODE
- MOV DI,OFFSET MENU_TYPE ;SET TO TYPE MENU STORE
- STOSB ;STORE MENU CODE
- MENU_CK_1: CMP MENU_TYPE,'1' ;MENU 1? EXIT WHEN RETURN HIT
- JNZ MENU_CK_2 ;NO
- MOV BX,OFFSET CHANGE_DIR ;GO TO
- MOV WORD PTR MENU_1,BX ; CHANGE DIR NOT SELECT
- MOV WORD PTR MENU_2,BX ; CHANGE DIR NOT SELECT
- MENU_CK_2: CMP MENU_TYPE,'2' ;MENU 2?
- JNZ MENU_CK_L ;NO
- MOV USE_DIRECTORY,32 ;DONT USE DIRECTORY NAME
- ;Menu "/M3" is used in CO.com
- ;Menu "/M4" is used in CO.com
- MENU_CK_L: JMP NEXT_SWITCH
- SAVE_DIR: PUSH CS ;Restore data segment.
- MOV DI,OFFSET USE_DIRECTORY ;SET TO BEGIN OF RECORD
- MOV SAVE_LAST_SLASH,DI ;SAVE POINTER
- SAVE_DIR_LOOP: LODSB
- CMP AL,13 ;End of parameters?
- JZ CK_SWITCH_END ;If yes, read data.
- CMP AL,32 ;End of parameter?
- JZ NEXT_SWITCH ;If yes, NEXT PARAM
- CHECK_COLEN: CMP AL,':' ;IS THERE A :
- JNE CHECK_SLASH
- MOV SAVE_LAST_SLASH,DI ;SAVE POINTER
- INC SAVE_LAST_SLASH
- CHECK_SLASH: CMP AL,'\' ;IS THERE A \
- JNE CHECK_ASTRISK
- MOV SAVE_LAST_SLASH,DI ;SAVE POINTER
- CHECK_ASTRISK: CMP AL,'*' ;IS THERE A *
- JNE CHECK_QUESTION
- MOV IS_THERE_FILE,1 ;SAY YES
- CHECK_QUESTION: CMP AL,'?' ;IS THERE A ?
- JNE CHECK_DONE
- MOV IS_THERE_FILE,1 ;SAY YES
- CHECK_DONE: CMP AL,'.' ;End of parameter?
- JZ SAVE_DIR_LOOP
- CMP AL,'A' ;End of parameter?
- JL CK_SWITCH_NT ;If yes, NEXT PARAM
- AND AL,5FH ;CAPITALIZE
- CK_SWITCH_NT: STOSB ;STORE IN USE_DIRECTORY
- JMP SAVE_DIR_LOOP
- CK_SWITCH_END:
- CMP IS_THERE_FILE,0 ;WAS THERE A FILE
- JE NO_FILE ;NO
- MOV SI,SAVE_LAST_SLASH
- LOOP_BLANKS: CMP BYTE PTR [SI],0
- JE NO_FILE
- MOV BYTE PTR [SI],32
- INC SI
- JMP LOOP_BLANKS
- NO_FILE: POP ES ;Restore segment.
- CMP SAVE_SORT+1,'I' ;IS PARM I
- JNZ READ
- ;--------------------------------------------------------------------
-
- INSTALL: MOV DX,103H ;If yes, point to signature.
- MOV AL,DATA_INT ;Retrieve free INT number.
- MOV AH,25H ;And install.
- INT 21H
- CALL FIRST_READ ;Read disk data.
- CALL CLS
- MOV DX,OFFSET INSTALL_MSG ;Display install message.
- MOV AH,9
- INT 21H
- CALL RESTORE_DRIVE ;Restore defaults.
- CALL CURSOR_ON
- MOV DX,OFFSET END_RESIDENT
- INT 27H ;Terminate and stay resident.
-
- ;-----------------------------------------------------;
- ; Check to see if drive request is a substitute. ;
- ; Also if different from current resident drive data. ;
- ;-----------------------------------------------------;
-
- CK_SUBST: MOV DATA_SEGMENT,ES ;Save the location of disk data.
- PUSH ES:CLUST_BYTES ;Retrieve from resident database
- POP CLUST_BYTES ; cluster size in bytes.
- MOV AL,DRIVE
- MOV DX,OFFSET UNKNOWN ;Is it a substituted drive?
- CMP AL,BYTE PTR DISK_BLOCK
- JZ CK_NEW_DRIVE ;If yes, exit with message.
- JMP DISK_EXIT
-
- CK_NEW_DRIVE: CMP AL,ES:DRIVE ;Is it a new drive request?
- JZ FORMAT ;If no, format resident data.
- MOV ES:DRIVE,AL ;Else, save new drive.
-
- ;--------------------------------------------------------------------;
- ; Read disk directory data, if necessary. Format it into a tree. ;
- ; Mark the current default directory. Clear the screen and display. ;
- ;--------------------------------------------------------------------;
-
- READ: CALL FIRST_READ
- FORMAT: CALL FORMAT_IT
- CALL GET_CURRENT
- ;--------------FW CHANGE---------------------------------------------
- CMP USE_DIRECTORY,32 ;USING A DIRECTORY NAME
- JNZ USE_SHORT_MENU
- MOV DEFAULT_MENU_NO,1 ;DEFAULT IS lONG MENU
- MOV DEFAULT_MENU,1 ;DEFAULT IS lONG MENU
- USE_SHORT_MENU:
- ;--------------------------------------------------------------------
- CALL CLS
- CALL START_DISPLAY
- ;--------------FW CHANGE---------------------------------------------
- ; CALL FILE_SUM ;WRITE NO FILES
- ;--------------------------------------------------------------------
-
- ;-----------------------------------------;
- ; We are now ready for business. We will ;
- ; loop here, waiting for user keystokes. ;
- ;-----------------------------------------;
-
- GET_KEY: CALL UPDATE_SCREEN
- CALL READ_KEY ;Get a keystroke.
- MOV BX,AX ;Save returned key.
- CMP AH,1 ;Is it Esc or below?
- JBE FUNCTION ;If yes, function.
- CMP AH,36H ;Is it right shift or above?
- JAE FUNCTION ;If yes, function.
- CMP AH,1CH ;Is it CR?
- JE FUNCTION ;If yes, function.
- MOV AH,2 ;Get shift state.
- INT 16H
- TEST AL,4 ;Is Ctrl depressed?
- JNZ FUNCTION ;If no, check function request.
- CALL SEARCH ;Else, search request.
- JMP SHORT GET_KEY
-
- FUNCTION: CMP DEFAULT_MENU,2
- JE FUNCTION2
-
- MOV DI,OFFSET DISPATCH_KEY
- MOV AL,BH
- MOV CX,DISPATCH_CNT ;Valid commands.
- REPNZ SCASB
- JNZ GET_KEY ;If no match, get another.
- MOV DI,OFFSET DISPATCH_END
- JMP FUNCTION_EXE
-
- FUNCTION2: MOV DI,OFFSET DISPATCH_KEY2
- MOV AL,BH
- MOV CX,DISPATCH_CNT2 ;Valid commands.
- REPNZ SCASB
- JNZ GET_KEY ;If no match, get another.
- MOV DI,OFFSET DISPATCH_END2
-
- FUNCTION_EXE: SHL CX,1
- SUB DI,CX
- CALL DS:[DI] ;Else do subroutine.
- ;--------------FW CHANGE---------------------------------------------
- ; CALL FILE_SUM ;WRITE NO FILES
- ;--------------------------------------------------------------------
- JMP SHORT GET_KEY ;Update screen; get next command.
-
- ;-------------------------------------------------------------------;
- ; This is the exit routine. Restore defaults the way we found them. ;
- ;-------------------------------------------------------------------;
-
- ESC_EXIT:
- MOV AL,DEFAULT_MENU_NO
- CMP DEFAULT_MENU,AL ;IS IT LONG MENU
- JE EXIT_PGM ;NO EXIT
- MOV DEFAULT_MENU,AL ;DEFAULT TO LONG MENU
- CALL START_DISPLAY ;AND DISPLAY IT
- RET
- EXIT_PGM: MOV DX,OFFSET CURRENT_DIR
- MOV TEMPUS_RETCODE,3 ;SET RETURN CODE
- CALL CD
- EXIT: CALL RESTORE_DRIVE
- CALL CLS
- CALL CURSOR_ON
- XOR DX,DX ;Home cursor.
- CALL SET_CURSOR
- MOV AL,TEMPUS_RETCODE ;SET RETURN CODE
- MOV AH,4CH
- INT 21H ;OUT
-
- ;*************;
- ; SUBROUTINES ;
- ;*************;
-
- ;-------------------------------------------------------------------;
- ; This function does nothing ;
- ;-------------------------------------------------------------------;
- NO_OP: RET
- HELP: RET
-
- ;------------------------------------------------------------------------;
- ; This subroutine MAKES A NEW DIRECORY FOR NEW USERS OF MAIN DIRECTORY ;
- ;------------------------------------------------------------------------;
-
- NEW_USER:
- CALL HOME_BAR
- CALL MKDIR
- RET
-
- ;------------------------------------------------------------------------;
- ; This subroutine CHANGES THE DEFAULT MENU FROM SHORT TO LONG ;
- ;------------------------------------------------------------------------;
-
- NEW_MENU:
- MOV DEFAULT_MENU,1 ;DEFAULT TO LONG MENU
- CALL START_DISPLAY ;AND DISPLAY IT
- RET
- ;------------------------------------------------------------------------;
- ; This subroutine searches for a directory with a specific first letter. ;
- ;------------------------------------------------------------------------;
-
- SEARCH: CMP BL,'a' ;Capitalize if lower case.
- JB SEARCH_IT
- CMP BL,'z'
- JA SEARCH_IT
- AND BL,5FH
- SEARCH_IT: CMP BL,'\' ;Searching for root?
- JNZ SEARCH_NAME
- CALL HOME_BAR ;If yes, home the bar.
- RET
-
- SEARCH_NAME: CALL GET_NAME ;Get current position.
- XOR DX,DX ;Zero out file counter.
- MOV DI,DIR_NAME ;Store current position in DI.
- MOV SI,OFFSET DIRECTORIES ;Point to top of listing.
- CMP BYTE PTR [DI],BL ;Are we currently at a match?
- JNZ INC_SEARCH ;If no, start from top.
- FIND_START: INC DX ;Increment count.
- ADD SI,DIR_RECORD ;Increment record.
- CMP SI,END_OFFSET ;End of tree?
- JAE SEARCH_BEEP ;If yes, no match.
- CMP SI,CUR_RECORD ;New record?
- JBE FIND_START ;If no, find it.
-
- NEXT_SEARCH: XOR BP,BP ;Zero in directory level pointer.
- FIND_DASH: INC BP
- CMP BYTE PTR [SI+BP-1],196 ;Is it the dash?
- JNZ FIND_DASH ;If no, find it.
-
- CMP BYTE PTR [SI+BP],BL ;Got a match?
- JZ FOUND_IT ;If yes, process.
- INC_SEARCH: ADD SI,DIR_RECORD ;Else, point to next record.
- INC DX
- CMP SI,END_OFFSET ;End of listing?
- JB NEXT_SEARCH ;If no, keep searching.
- SEARCH_BEEP: CALL BEEP ;No matches, so beep.
- RET
-
- FOUND_IT: MOV CX,DIR_COUNT ;Retrieve directory count.
- SUB CX,DX ;Subtract search count.
- MOV SEARCH_COUNT,CX ;And store.
- MOV CL,ATTR_TREE ;Turn off bar for now.
- MOV BAR_ATTRIBUTE,CL
- CALL END_BAR ;First move to end.
- JMP SHORT MARK_IT
- NEXT_UP: CALL UP_ARROW2 ;Move up to matching filename.
- MARK_IT: DEC SEARCH_COUNT
- JNZ NEXT_UP
- MOV CL,INVERSE ;Turn bar back on and display.
- MOV BAR_ATTRIBUTE,CL
- XOR BP,BP
- CALL SCROLL_BAR
- RET
-
- ;-------------------------------------------------------------------------;
- ; This subroutine changes the directory to the one highlighted and exits. ;
- ;-------------------------------------------------------------------------;
-
- SELECT_DIR: CALL GET_NAME
- CALL NEW_DIR
- CALL CO1
- CMP TEMPUS_RETCODE,4 ; pgm NOT fOUND
- JNZ SELECT_CO
-
- CALL START_DISPLAY ;Restore menu.
- CALL CLEAR_MSG
- MOV DX,1629H ;Else, display Warning.
- MOV SI,OFFSET PATH_ERROR
- CALL DISPLAY_TEXT
- RET ;CAN'T FIND co.com
-
- SELECT_CO: CMP TEMPUS_RETCODE,3 ; ESC HIT
- JNZ SELECT_DIR_EXIT
- CALL START_DISPLAY ;Restore menu.
- RET
- SELECT_DIR_EXIT: JMP EXIT ;Exit.
-
- ;-------------------------------------------------------------------------;
- ; This subroutine changes the directory to the one highlighted and exits. ;
- ;-------------------------------------------------------------------------;
-
- CHANGE_DIR: CALL GET_NAME
- CALL NEW_DIR
- JMP EXIT ;Exit.
-
- ;----------------------------------------------------;
- ; This subroutine renames the highlighted directory. ;
- ;----------------------------------------------------;
-
- RENAME: CMP DOS_VERSION,3 ;Can't rename directories before
- JB RENAME_ERROR ; DOS 3.x
- CALL CLEAR_MSG
- CALL GET_NAME
- CMP SI,OFFSET DIRECTORIES ;Can't rename the root directory.
- JZ RENAME_ERROR
- CALL NEW_DIR ;Change to the requested directory.
- JC RENAME_READ ;If nonexistant, reread data.
-
- MOV DX,162CH ;Row 22, column 44.
- MOV SI,OFFSET RENAME_MSG ;Display rename message.
- CALL QUERY ;Get new name from user.
- JC RENAME_END ;If carry, Esc was pressed.
-
- MOV DX,OFFSET DOT_DOT ;Change to parent directory.
- CALL CD
- MOV DX,DIR_NAME ;Point to old name.
- MOV DI,80H
- MOV AH,56H ;Rename.
- INT 21H
- JC RENAME_ERROR ;Beep if illegal.
- RENAME_READ: CALL REREAD ;Reread data.
- RENAME_END: CALL CLEAR_MSG
- RET
-
- RENAME_ERROR: CALL BEEP ;Error exit.
- CALL CLEAR_MSG
- RET
-
- ;-----------------------------------------------------------------------;
- ; This subroutine makes a subdirectory under the highlighted directory. ;
- ;-----------------------------------------------------------------------;
-
- MKDIR: CALL CLEAR_MSG
- CALL GET_NAME
- CALL NEW_DIR ;Change to the requested directory.
- JC MKDIR_READ ;If nonexistant, reread data.
- MOV DX,1529H ;Row 21; column 41.
- MOV SI,OFFSET PATH_LENGTH ;Display path message.
- CALL DISPLAY_TEXT
- CALL GET_COUNT ;And the path length.
- CALL GET_TEXT ;And end of message.
- CMP COUNT,63 ;Is it already 63 or more chars?
- JB MKDIR_QUERY
- CALL BEEP ;If yes, refuse to make directory.
- CALL DELAY
- JMP SHORT MKDIR_END
-
- MKDIR_QUERY: MOV DX,1629H ;Row 21; column 41.
- MOV SI,OFFSET MKDIR_MSG1 ;Display path message.
- CALL DISPLAY_TEXT
- MOV DX,1729H ;Point to next row.
- CALL QUERY ;Get name from user.
- JC MKDIR_END ;If carry, Esc was pressed.
- MOV DX,80H
- MOV AH,39H ;Create the directory.
- INT 21H
- JC MKDIR_ERROR ;Beep if illegal.
- MKDIR_READ: CALL REREAD ;Reread data.
-
- MKDIR_END: CALL CLEAR_MSG
- RET
-
- MKDIR_ERROR: CALL BEEP ;Error exit.
- CALL CLEAR_MSG
- RET
-
- ;-------------------------------------------------------;
- ; This subroutine removes the highlighted subdirectory. ;
- ;-------------------------------------------------------;
-
- RMDIR: CALL CLEAR_MSG
- CALL GET_NAME
- MOV SI,DIR_NAME
- CMP SI,OFFSET DIRECTORIES ;Can't remove root directory.
- JNZ RMDIRG
- JMP RMDIR_ERROR
- RMDIRG: CMP BYTE PTR [SI+DIR_RECORD+1],196 ;Can't remove directory
- JNZ RMDIRD
- JMP RMDIR_ERROR
- RMDIRD: CALL NEW_DIR ;Change to requested directory.
- JNC RMDIRH ;If nonexistant, reread data.
- JMP RMDIR_READ ;If nonexistant, reread data.
- RMDIRH: MOV DX,OFFSET DTA_AREA ;Restore Disk Transfer Address.
- MOV AH,1AH
- INT 21H
- CALL CLEAR_MSG
- CALL COUNT_THEM ;Count and display file count.
- CMP COUNT,0 ;If empty, remove directory.
- JZ REMOVE
-
- MOV DX,1729H ;Else, display file loss Warning.
- MOV SI,OFFSET RMDIR_MSG
- CALL DISPLAY_TEXT
- MOV DX,1829H
- CALL DISPLAY_TEXT
- CALL CURSOR_ON
- CALL READ_KEY ;Get response.
- CMP AH,K_Y ;If not "Y", exit.
- JNZ RMDIR_RETURN
- CALL WRITE_TEXT ;Else, display it.
- CALL READ_KEY ;Get next response.
- CMP AH,1CH ;If not carriage return, exit.
- JNZ RMDIR_RETURN
- ;----------------------------------------------------------------------
- CALL CLEAR_MSG
- MOV DX,1629H ;Else, display file loss Warning.
- MOV SI,OFFSET RMDIR_MSG2
- CALL DISPLAY_TEXT
- MOV DX,1829H
- CALL DISPLAY_TEXT
- CALL CURSOR_ON
- CALL READ_KEY ;Get response.
- CMP AH,K_Y ;If not "Y", exit.
- JNZ RMDIR_RETURN
- ;----------------------------------------------------------------------
-
- CALL FIRST_MATCH ;Else, find all files and delete.
- CALL DELETE
- NEXT_DELETE: CALL NEXT_MATCHING
- JC REMOVE
- CALL DELETE
- JMP SHORT NEXT_DELETE
-
- REMOVE: MOV DX,OFFSET DOT_DOT ;Move to parent directory.
- CALL CD
- MOV DX,DIR_NAME
- MOV AH,3AH ;Remove requested directory.
- INT 21H
- JC RMDIR_ERROR
- RMDIR_READ: CALL REREAD ;Reread data.
- RMDIR_RETURN: CALL CLEAR_MSG
- CMP COUNT,0 ;If empty, remove directory.
- JNZ RMDIR_EXIT
- MOV DX,1629H ;Else, display file loss Warning.
- MOV SI,OFFSET RMDIR_MSG0
- CALL DISPLAY_TEXT
- RMDIR_EXIT: RET
-
- RMDIR_ERROR: CALL BEEP ;Error exit.
- ; CALL CLEAR_MSG
- RET
-
- ;------------------------------------------------------------------;
- ; These two subroutines hide and unhide the highlighted directory. ;
- ;------------------------------------------------------------------;
-
- HIDE_UNHIDE: CALL GET_NAME
- CMP SI,OFFSET DIRECTORIES ;Can't hide root directory.
- JZ HIDE_ERROR
- MOV DX,1629H ;Row 22; column 41.
- MOV SI,OFFSET HIDE_MSG ;Display hide message.
- CALL DISPLAY_TEXT
- MOV SI,DIR_NAME
- CALL GET_TEXT
- MOV BP,2 ;Hidden attribute.
- CALL READ_KEY ;Get a keystroke.
- CMP AH,23H ;Is it "H"?
- JZ CHANGE_IT ;If yes, change attribute.
- XOR BP,BP ;Turn off hidden attribute.
- CMP AH,16H ;Is it "U"?
- JNZ HIDE_END ;If no, exit.
-
- CHANGE_IT: CALL NEW_DIR
- JC HIDE_READ ;If directory nonexistant, read.
- MOV DX,OFFSET DOT_DOT ;Change to parent directory.
- CALL CD
- MOV DX,DIR_NAME
- MOV CX,BP ;Retrieve requested attribute.
- CALL CHMOD ;And change it.
- HIDE_READ: CALL REREAD
- RET
-
- HIDE_ERROR: CALL BEEP
- HIDE_END: CALL CLEAR_MSG
- RET
-
- ;--------------------------------------------------------;
- ; This subroutine sets or resets the read-only attribute ;
- ; of all the files of the highlighted directory. ;
- ;--------------------------------------------------------;
-
- READ_ONLY: CALL GET_NAME
- CALL NEW_DIR
- JC SET_READ ;If nonexistant directory, reread.
- CALL COUNT_THEM ;Display file count.
- CMP COUNT,0 ;Is directory empty?
- JZ READ_END ;If yes, nothing to mark.
- MOV DX,1729H ;Row 23; column 41.
- MOV SI,OFFSET READ_ONLY_MSG ;Display read-only message.
- CALL DISPLAY_TEXT
- MOV STRIP_MASK,11111111xB ;If read-only request, nothing
- MOV ADD_MASK, 00000001B ; to strip and add bit 1.
- CALL READ_KEY
- CMP AH,13H ;Is it "R"?
- JZ DO_READ ;If yes, turn on read-only bit.
- MOV STRIP_MASK,11111110xB ;If NOT read-only request, strip
- MOV ADD_MASK,0 ; read-only bit and add nothing.
- CMP AH,16H ;Is it "U"?
- JNZ READ_RETURN ;If no, done here.
-
- DO_READ: CALL DO_ATTRIB ;Change the attribute.
- CALL CLEAR_LINE ;Clear keystroke prompt line.
- MOV DX,1729H ;Row 23; column 41.
- MOV SI,OFFSET HAVE_BEEN ;Display "have been" message.
- CALL DISPLAY_TEXT
- MOV SI,OFFSET READ_MSG ;Display rest of message.
- JMP SHORT SET_MSG
-
- READ_RETURN: CALL CLEAR_MSG
- RET
-
- READ_END: CALL DELAY
- RET
-
- SET_READ: CALL REREAD
- RET
-
- ;------------------------------------------------------;
- ; These two subroutines set and reset the archive bit. ;
- ;------------------------------------------------------;
-
- SET_RESET: CALL GET_NAME
- CALL NEW_DIR
- JC SET_READ ;If nonexistant directory, reread.
- CALL COUNT_THEM ;Display file count.
- CMP COUNT,0 ;Is directory empty?
- JZ SET_END ;If yes, nothing to mark.
- MOV DX,1729H ;Row 23; column 41.
- MOV SI,OFFSET ARCHIVE_MSG ;Display archive message.
- CALL DISPLAY_TEXT
- MOV STRIP_MASK,11111111xB ;If set archive request, nothing
- MOV ADD_MASK, 00100000xB ; to strip and add bit 1.
- CALL READ_KEY
- CMP AH,1FH ;Is it "S"?
- JZ DO_ARCHIVE ;If yes, turn on archive bit.
- MOV STRIP_MASK,11011111xB ;If NOT archive request, strip
- MOV ADD_MASK,0 ; archive bit and add nothing.
- CMP AH,13H ;Is it "R"?
- JNZ READ_RETURN ;If no, done here.
-
- DO_ARCHIVE: CALL DO_ATTRIB ;Change the attribute.
- CALL CLEAR_LINE ;Clear keystroke prompt line.
- MOV DX,1729H ;Row 23; column 41.
- MOV SI,OFFSET HAVE_BEEN ;Display "have been" message.
- CALL DISPLAY_TEXT
-
- SET_MSG: CMP ADD_MASK,0 ;If add nothing, display strip
- JZ DISPLAY_MSG ; message.
- ADD SI,4 ;Else, display bit on message.
- DISPLAY_MSG: CALL GET_TEXT
- SET_END: CALL DELAY ;Wait for keystroke, then remove
- RET ; message.
-
- ;-----------------------------------------------;
- ; This subroutine displays the file count and ;
- ; displacement of the highlighted subdirectory. ;
- ;-----------------------------------------------;
-
- FILE_SUM: CALL CLEAR_MSG ;CLEAR PREV MSG
- CALL GET_NAME
- CALL NEW_DIR ;Change to requested directory.
- ; JC REREAD ;If nonexistant, reread data.
-
- MOV DX,OFFSET DTA_AREA ;Restore Disk Transfer Address.
- MOV AH,1AH
- INT 21H
-
- CALL COUNT_THEM ;Get file count and displacement.
- ; CALL DELAY ;Display count until keystroke.
- RET
-
- ;-------------------------------------------------------------------;
- ; This subroutine rereads the directory tree information from disk. ;
- ;-------------------------------------------------------------------;
-
- REREAD: MOV PAGE_END,21*160+PAGE_START ;Reset default values.
- MOV DIR_COUNT,1
- CALL CLEAR_MSG ;Clear the last message.
- MOV DX,162DH ;Row 22, column 45.
- MOV SI,OFFSET LOADING ;Display loading message.
- CALL DISPLAY_TEXT
- CALL READ_DATA ;Read the data.
- CALL FORMAT_IT ;Construct new tree.
- CALL START_DISPLAY ;Display menu.
- CALL CLEAR_MSG ;Clear sorting message.
- XOR BP,BP ;Update directory display.
- CALL SCROLL
- MOV SI,PAGE_END ;Move bar if below directory
- SUB SI,160 ; display.
- CMP SI,LINE
- JA REREAD_END
- CALL MOVE_BAR
- REREAD_END: RET
- ;-----------------------------------------------;
- ; This subroutine SETS Backup/Restore parameters;
- ;-----------------------------------------------;
-
- B_R_OPTIONS:
- CALL BRDRIVE
- CALL BRPATH
- CALL BROPTIONS
- RET
-
- ;-----------------------------------------------;
- ; This subroutine SETS Backup/Restore DRIVE ;
- ;-----------------------------------------------;
-
- BRDRIVE:
- CALL CLEAR_MSG
- MOV DX,162CH ;Row 22, column 44.
- MOV SI,OFFSET BRDRIVE_MSG
- MOV DI,80H ;INPUT SAVE
- MOV CX,2 ;NO INPUT CHARS ALLOWED
- CALL BRQUERY
- JC BRDRIVE_RET ;If carry, Esc was pressed.
- MOV SI,80H ;INPUT SAVE
- MOV AL,BYTE PTR [SI]
- AND AL,5FH ;CAPITALIZE
- CMP AL,'A'
- JB BRDRIVE_RET
- CMP AL,'Z'
- JA BRDRIVE_RET
- MOV CX,1 ;NO INPUT CHARS ALLOWED
- MOV DI,OFFSET ODRIVE
- REP MOVSB
- BRDRIVE_RET:
- CLC
- ; CALL CLEAR_MSG
- CALL START_DISPLAY
- RET
- ;-----------------------------------------------;
- ; This subroutine SETS Backup/Restore PATH ;
- ;-----------------------------------------------;
-
- BRPATH:
- CALL CLEAR_MSG
- MOV DX,162CH ;Row 22, column 44.
- MOV SI,OFFSET BRPATH_MSG ;MSG
- MOV DI,80H ;INPUT SAVE
- MOV CX,12 ;NO INPUT CHARS ALLOWED
- CALL BRQUERY
- JC BRPATH_RET ;If carry, Esc was pressed.
- MOV CX,12 ;NO INPUT CHARS ALLOWED
- MOV SI,80H ;INPUT SAVE
- MOV DI,OFFSET OPATH
- REP MOVSB
- BRPATH_RET:
- CLC
- ; CALL CLEAR_MSG
- CALL START_DISPLAY
- RET
- ;-----------------------------------------------;
- ; This subroutine SETS Backup/Restore OPTIONS ;
- ;-----------------------------------------------;
-
- BROPTIONS:
- CALL CLEAR_MSG
- MOV DX,162CH ;Row 22, column 44.
- MOV SI,OFFSET BROPTIONS_MSG ;MSG
- MOV DI,80H ;INPUT SAVE
- MOV CX,18 ;NO INPUT CHARS ALLOWED
- CALL BRQUERY
- JC BROPTIONS_RET ;If carry, Esc was pressed.
- MOV CX,18 ;NO INPUT CHARS ALLOWED
- MOV SI,80H ;INPUT SAVE
- MOV DI,OFFSET OOPTIONS
- REP MOVSB
- BROPTIONS_RET:
- CLC
- ; CALL CLEAR_MSG
- CALL START_DISPLAY
- RET
-
- ;-----------------------------------------------;
- ; This subroutine spawns COMMAND COM FOR BACKUP ;
- ;-----------------------------------------------;
-
- BACKUP:
- MOV USE_DIR_EQ," "
- MOV AX,CUR_OFFSET
- MOV CUR_OFFSET_SAVE,AX ;SAVE OFFSET
- MOV AX,LINE
- MOV LINE_SAVE,AX ;SAVE LINE
- MOV T_CLUST_COUNT_1_2MEG,0 ;And cluster counter.
- MOV T_CLUST_COUNT_1_4MEG,0 ;And cluster counter.
- MOV T_CLUST_COUNT_360K,0 ;And cluster counter.
- MOV AT_LAST_LINE,"0"
-
- CALL FILE_SUM ;WRITE NO FILES
- MOV AX,CLUST_COUNT_1_2MEG ;GET CUR Cluster counter.
- MOV T_CLUST_COUNT_1_2MEG,AX ;SAVE IN TOTAL
- MOV AX,CLUST_COUNT_1_4MEG ;GET CUR Cluster counter.
- MOV T_CLUST_COUNT_1_4MEG,AX ;SAVE IN TOTAL
- MOV AX,CLUST_COUNT_360K ;GET CUR Cluster counter.
- MOV T_CLUST_COUNT_360K,AX ;SAVE IN TOTAL
- CALL GET_NAME
- MOV BX,CUR_LEVEL ;GET LEVEL OF CUR DIR
- MOV CUR_LEVEL_SAVE,BX ;SAVE IT FOR LATER
- CALL NEW_DIR ;Change the default directory.
- CMP USE_DIRECTORY,32 ;IS THERE SPECIAL DIRECTORY NAME
- JE BACKUP_COUNT
- MOV SI,DIR_NAME ;LOAD NAME USER POINTING AT
- MOV DI,OFFSET USE_DIRECTORY ;LOAD SPEC NAME
- MOV CX,11 ; COUNT FOR COMPARE
- REPE CMPSB
- JE BACKUP_EQU ; NOT EQUAL BYPASS
- CMP BYTE PTR [DI],32 ; HIT BLANKS
- JNZ BACKUP_COUNT ; NOT EQUAL BYPASS
- CMP BYTE PTR [SI],00 ; HIT BLANKS
- JNZ BACKUP_COUNT ; NOT EQUAL BYPASS
- BACKUP_EQU: MOV USE_DIR_EQ,"=" ; SAY EQUAL
- MOV T_CLUST_COUNT_1_2MEG,0 ;RESET cluster counter.
- MOV T_CLUST_COUNT_1_4MEG,0 ;RESET cluster counter.
- MOV T_CLUST_COUNT_360K,0 ;RESET cluster counter.
- BACKUP_COUNT:
- CALL DN_ARROW2 ; DOWN ONE
- CMP AT_LAST_LINE,"=" ;AT LIST LINE THEN OUT
- JE BACKUP_COUNT_END ;DONE IS LAST ENTRY
- CALL FILE_SUM ;WRITE NO FILES
- MOV AX,CUR_LEVEL ;GET LEVEL OF CUR DIR
- CMP AX,CUR_LEVEL_SAVE ;LOAD ORIG LEVEL
- JBE BACKUP_COUNT_END
- MOV AX,CLUST_COUNT_1_2MEG ;GET CUR Cluster counter.
- ADD T_CLUST_COUNT_1_2MEG,AX ;SAVE IN TOTAL
- MOV AX,CLUST_COUNT_1_4MEG ;GET CUR Cluster counter.
- ADD T_CLUST_COUNT_1_4MEG,AX ;SAVE IN TOTAL
- MOV AX,CLUST_COUNT_360K ;GET CUR Cluster counter.
- ADD T_CLUST_COUNT_360K,AX ;SAVE IN TOTAL
- JMP BACKUP_COUNT ;DO AGAIN
-
- BACKUP_COUNT_END:
- MOV AX,CUR_OFFSET_SAVE
- MOV CUR_OFFSET,AX ;RESTORE OFFSET
- MOV AX,LINE_SAVE
- MOV LINE,AX ;RESTORE LINE
- CALL START_DISPLAY ;Restore menu.
- CALL UPDATE_SCREEN
- MOV DISKS_1_2MEG,0
- XOR DX,DX ;Zero in high half.
- MOV AX,T_CLUST_COUNT_1_2MEG ;CNT OF 1.2MEG CLUSTERS USED
- DIV CLUSTERS_1_2MEG ;Divide to get NO DISKS
- OR DX,DX ;If remainder, increment count.
- JZ NO_REM_1_2MEG_T
- INC DISKS_1_2MEG
- NO_REM_1_2MEG_T: ADD DISKS_1_2MEG,AX ;Add DISK count.
-
- MOV DISKS_1_4MEG,0
- XOR DX,DX ;Zero in high half.
- MOV AX,T_CLUST_COUNT_1_4MEG ;CNT OF 1.24EG CLUSTERS USED
- DIV CLUSTERS_1_4MEG ;Divide to get NO DISKS
- OR DX,DX ;If remainder, increment count.
- JZ NO_REM_1_4MEG_T
- INC DISKS_1_4MEG
- NO_REM_1_4MEG_T: ADD DISKS_1_4MEG,AX ;Add DISK count.
-
- MOV DISKS_360K,0
- XOR DX,DX ;Zero in high half.
- MOV AX,T_CLUST_COUNT_360K ;CNT OF 360K CLUSTERS USED
- DIV CLUSTERS_360K ;Divide to get NO DISKS
- OR DX,DX ;If remainder, increment count.
- JZ NO_REM_360K_T
- INC DISKS_360K
- NO_REM_360K_T: ADD DISKS_360K,AX ;Add DISK count.
-
- CALL CLEAR_MSG
- MOV DX,1529H ;Row 22; column 41.
- CALL SET_CURSOR
- MOV SI,OFFSET FORMAT_MSG ;DISPLAY FORMAT MSG
- CALL GET_TEXT
- MOV DX,1629H ;Row 22; column 41.
- CALL SET_CURSOR
- MOV SI,OFFSET BACKUP_USES ;DISPLAY MESSAGE
- CALL GET_TEXT
- MOV AX,DISKS_1_2MEG
- MOV COUNT,AX ;1.2MEG COUNT
- CALL GET_COUNT ;Display count.
- MOV SI,OFFSET BACKUP_USES_1_2MEG ;DISPLAY MESSAGE
- CALL GET_TEXT
-
- MOV DX,1729H ;Row 22; column 41.
- CALL SET_CURSOR
- MOV SI,OFFSET BACKUP_USES ;DISPLAY MESSAGE
- CALL GET_TEXT
- MOV AX,DISKS_1_4MEG
- MOV COUNT,AX ;1.2MEG COUNT
- CALL GET_COUNT ;Display count.
- MOV SI,OFFSET BACKUP_USES_1_4MEG ;DISPLAY MESSAGE
- CALL GET_TEXT
-
- MOV DX,1829H ;Row 23; column 41.
- CALL SET_CURSOR
- MOV SI,OFFSET BACKUP_USES ;DISPLAY MESSAGE
- CALL GET_TEXT
- MOV AX,DISKS_360K
- MOV COUNT,AX ;360K COUNT
- CALL GET_COUNT ;Display count.
- MOV SI,OFFSET BACKUP_USES_360K ;DISPLAY MESSAGE
- CALL GET_TEXT
- BACKUP_READ: CALL READ_KEY
- CMP AH,K_ESC
- JNE BACKUP_NO_ESC
- JMP BACKUP_EXIT
- BACKUP_NO_ESC: CMP AH,K_N
- JE FORMAT_NONE
- CMP AH,K_Y
- JE FORMAT_SOME
- CMP AH,K_ENTER
- JE FORMAT_NONE
- JMP BACKUP_READ
- ;----------------------------------------------------------------------
- FORMAT_SOME:
- CALL CLS ;Clear screen.
- MOV SI,OFFSET PARA_FORMAT ; NAME OF PGM
- MOV DI,OFFSET PARA_BR+1 ; MOVE TO
- CALL MOVE_TEXT
- MOV CX,2 ;NO INPUT CHARS ALLOWED
- MOV SI,OFFSET ODRIVE
- REP MOVSB
- MOV BYTE PTR [DI],13
- MOV SI,OFFSET PARA_BR+1 ; MOVE TO
- SUB DI,SI
- MOV AX,DI
- MOV PARA_BR,AL ;STORE LENGTH
- MOV BX,OFFSET PARA_BR ;LOAD OUT PARM FOR CHILD
- MOV WORD PTR COM_LINE_PTR,BX
- CALL COMMAND_COM ;DO FORMAT
- FORMAT_NONE:
- MOV PARA_ADD," "
- MOV AT_LAST_LINE,0
- CALL FILE_SUM ;WRITE NO FILES
- BACKUP_LOOP: CMP AT_LAST_LINE,"=" ;AT LAST LINE THEN OUT
- JNE BACKUP_NO_EQ
- JMP BACKUP_EXIT
- BACKUP_NO_EQ: CMP USE_DIR_EQ,"=" ; EQUAL SPECIAL
- JNE BACKUP_CD ;DONE IS LAST ENTRY
- CALL DN_ARROW2 ; DOWN ONE
- CMP AT_LAST_LINE,"=" ;AT LAST LINE THEN OUT
- JE BACKUP_EXIT
-
- BACKUP_CD: MOV SI,OFFSET PARA_BACKUP ; NAME OF PGM
- MOV DI,OFFSET PARA_BR+1 ; MOVE TO
- CALL MOVE_TEXT
- MOV AH,19H ;Get default drive and save.
- INT 21H
- ADD AL,'A' ;CONVERT TO ASCII DRIVE
- STOSB
- MOV AL,':' ;CONVERT TO ASCII DRIVE
- STOSB
- MOV CX,12 ;NO INPUT CHARS ALLOWED
- MOV SI,OFFSET OPATH
- REP MOVSB
- MOV BYTE PTR [DI],32
- INC DI
- MOV CX,2 ;NO INPUT CHARS ALLOWED
- MOV SI,OFFSET ODRIVE
- REP MOVSB
- MOV BYTE PTR [DI],32
- INC DI
- MOV CX,18 ;NO INPUT CHARS ALLOWED
- MOV SI,OFFSET OOPTIONS
- REP MOVSB
- CMP USE_DIR_EQ,"=" ; IS SPECIAL DIR
- JNE BACKUP_NO_SPEC
- MOV BYTE PTR [DI],32
- INC DI
- MOV CX,2 ;ADD /A TO PARMS
- MOV SI,OFFSET PARA_ADD
- REP MOVSB
- BACKUP_NO_SPEC:
- MOV BYTE PTR [DI],13
- MOV SI,OFFSET PARA_BR+1 ; MOVE TO
- SUB DI,SI
- MOV AX,DI
- MOV PARA_BR,AL ;STORE LENGTH
- MOV BX,OFFSET PARA_BR ;LOAD OUT PARM FOR CHILD
- MOV WORD PTR COM_LINE_PTR,BX
- CALL CLS ;Clear screen.
- CALL COMMAND_COM ;DO BACKUP
- MOV PARA_ADD,"A/"
- CMP USE_DIR_EQ,"=" ; IS SPECIAL DIR
- JNE BACKUP_EXIT
- JMP BACKUP_LOOP
-
- BACKUP_EXIT: MOV AX,CUR_OFFSET_SAVE
- MOV CUR_OFFSET,AX ;RESTORE OFFSET
- MOV AX,LINE_SAVE
- MOV LINE,AX ;RESTORE LINE
- CALL CLS ;Clear screen.
- CALL START_DISPLAY ;Restore menu.
- CALL FILE_SUM ;WRITE NO FILES
- RET
-
- ;-----------------------------------------------;
- ; This subroutine spawns COMMAND COM FOR RESTORE;
- ;-----------------------------------------------;
-
- RESTORE:
- CALL GET_NAME ;Change the default directory.
- CALL NEW_DIR ;Change the default directory.
-
- MOV SI,OFFSET PARA_RESTORE ; NAME OF PGM
- MOV DI,OFFSET PARA_BR+1 ; MOVE TO
- CALL MOVE_TEXT
- MOV CX,2 ;NO INPUT CHARS ALLOWED
- MOV SI,OFFSET ODRIVE
- REP MOVSB
- MOV BYTE PTR [DI],32
- INC DI
- MOV CX,12 ;NO INPUT CHARS ALLOWED
- MOV SI,OFFSET OPATH
- REP MOVSB
- MOV BYTE PTR [DI],32
- INC DI
- MOV CX,18 ;NO INPUT CHARS ALLOWED
- MOV SI,OFFSET OOPTIONS
- REP MOVSB
- MOV BYTE PTR [DI],13
- MOV SI,OFFSET PARA_BR+1 ; MOVE TO
- SUB DI,SI
- MOV AX,DI
- MOV PARA_BR,AL ;STORE LENGTH
- MOV BX,OFFSET PARA_BR ;LOAD OUT PARM FOR CHILD
- MOV WORD PTR COM_LINE_PTR,BX
- CALL COMMAND_COM ;DO BACKUP
-
- RESTORE_EXIT:
- CALL CLS ;Clear screen.
- CALL START_DISPLAY ;Restore menu.
- RET
-
- ;---------------------------------------------;
- ; This subroutine spawns CO. WITH COMMAND.COM ;
- ;---------------------------------------------;
- CO: MOV SI,OFFSET PARAMETER ;LOAD OUT PARM FOR CHILD
- MOV DI,OFFSET PARA_BR+1 ; MOVE TO
- CALL MOVE_TEXT
- MOV BYTE PTR [DI],13
- MOV SI,OFFSET PARA_BR+1 ; MOVE TO
- SUB DI,SI
- MOV AX,DI
- MOV PARA_BR,AL ;STORE LENGTH
- MOV BX,OFFSET PARA_BR ;LOAD OUT PARM FOR CHILD
- MOV WORD PTR COM_LINE_PTR,BX
-
- CALL COMMAND_COM ;DO BACKUP
- CALL CLS ;Clear screen.
- CALL START_DISPLAY ;Restore menu.
- RET
-
- ;-------------------------------------------------------------------;
- ; This function EXITS TO DOS ;
- ;-------------------------------------------------------------------;
- EXIT_DOS:
- CALL CLS ;Clear screen.
- CALL CURSOR_ON ;Turn it on.
- CALL CURSOR_ON ;Turn it on.
- CALL CURSOR_ON ;Turn it on.
- XOR DX,DX ;Home cursor.
- CALL SET_CURSOR
- MOV PARA_BR,00
- MOV BX,OFFSET PARA_BR ;LOAD OUT PARM FOR CHILD
- MOV WORD PTR COM_LINE_PTR,BX
- CALL COMMAND_COM ;DO BACKUP
- CALL CLS ;Clear screen.
- CALL CURSOR_OFF ;Turn it on.
- CALL START_DISPLAY ;Restore menu.
- RET
-
- COMMAND_COM: CALL GET_NAME
- CALL NEW_DIR ;Change the default directory.
- MOV BX,1000H ;Shrink memory down to one segment.
- MOV AH,4AH
- INT 21H
-
- PUSH DS ;Save segment registers.
- PUSH ES
- CALL CLS ;Clear screen.
- CLI
- MOV STACK_SEG,SS ;Save stack segment and pointer.
- MOV STACK_PTR,SP
- STI
-
- MOV WORD PTR COM_LINE_PTR + 2,DS
- MOV AX,DS:[2CH] ;Retrieve environment segment.
- MOV ENVIRONMENT,AX ;And put in paramter block.
- MOV DS,AX ;And data segment.
- XOR AX,AX ;Zero out pointer.
- FIND_COMSPEC: MOV SI,AX ;Point to environment offset.
- INC AX ;Next offset.
- CMP WORD PTR[SI+1],0000H ;END OF ENVIRONMENT?
- JE NOCOMSPEC ;YES
- MOV DI,OFFSET COMSPEC ;Find "Comspec=".
- MOV CX,8
- REP CMPSB
- JNZ FIND_COMSPEC
- MOV DX,SI ;What follows is Command.com path.
-
- MOV BX,OFFSET ENVIRONMENT ;Point to parameter block.
- MOV AX,4B00H ;Execute.
- INT 21H
-
- MOV AX,4D00H ;Get Return Code
- INT 21H
- MOV DI,OFFSET TEMPUS_RETCODE ;Load Return Code Addr
- STOSB
-
- NOCOMSPEC: CLI
- MOV SP,CS:STACK_PTR ;Restore stack segment and pointer.
- MOV SS,CS:STACK_SEG
- STI
- POP ES ;Restore segment registers.
- POP DS
-
- MOV DX,80H ;Restore Disk Transfer Address.
- MOV AH,1AH
- INT 21H
- MOV BX,2000H ;Restore dual memory segments.
- MOV AH,4AH
- INT 21H
- RET
-
- ;-----------------------------------------------;
- ; This subroutine spawns CO. ;
- ;-----------------------------------------------;
-
- CO1: CALL GET_NAME
- CALL NEW_DIR ;Change the default directory.
- MOV BX,1000H ;Shrink memory down to one segment.
- MOV AH,4AH
- INT 21H
-
- PUSH DS ;Save segment registers.
- PUSH ES
- CALL CLS ;Clear screen.
- CLI
- MOV STACK_SEG,SS ;Save stack segment and pointer.
- MOV STACK_PTR,SP
- STI
-
- MOV DI,OFFSET PATH_FOR_PGM ;MOVE WORK AREA
- MOV AL,DEFAULT_DRIVE ;DEFAULT DRIVE
- ADD AL,'A' ;MAKE ASCII
- STOSB
- MOV AL,':'
- STOSB
- MOV SI,OFFSET DEFAULT_DIR ;DEFAULT DIR
- CALL MOVE_TEXT ;
- MOV SI,OFFSET LOAD_NAME_CO ;DEFAULT DIR
- CALL MOVE_TEXT ;
- MOV BYTE PTR [DI],00 ;END OF NAME
- INC DI ;
-
- MOV WORD PTR COM_LINE_PTR + 2,DS
- MOV BX,OFFSET PARAMETER ;LOAD OUT PARM FOR CHILD
- MOV WORD PTR COM_LINE_PTR,BX
- MOV AX,DS:[2CH] ;Retrieve environment segment.
- MOV ENVIRONMENT,AX ;And put in paramter block.
- MOV DS,AX ;And data segment.
- XOR AX,AX ;Zero out pointer.
- FIND_COMSPEC1: MOV SI,AX ;Point to environment offset.
- INC AX ;Next offset.
- MOV BX,WORD PTR[SI+1] ;
- CMP BX,0000H ;END OF ENVIRONMENT?
- JNZ CONTPATH ;YES
-
- JMP PATH_CONT
-
- CONTPATH: MOV DI,OFFSET PATH ;Find "PATH="
- MOV CX,6
- REP CMPSB
- JNZ FIND_COMSPEC1
- PATH_CONT: ;What follows is PATH NAMES
- MOV AX,DS ;POINT TO CS
- MOV BX,SI ;POINT TO CS
- MOV DS,CS ;POINT TO CS
- MOV SAVE_DS_PATH,AX ;SAVE ADDR OF PATH
- MOV SAVE_SI_PATH,BX ;SAVE ADDR OF PATH
- TRY_AGAIN: MOV DS,CS ;POINT TO CS
- MOV WORD PTR COM_LINE_PTR + 2,CS
- MOV BX,OFFSET PARM_SAVE_LGTH ;LOAD OUT PARM FOR CHILD
- MOV WORD PTR COM_LINE_PTR,BX
- MOV DX,OFFSET PATH_FOR_PGM ;Point to PGM NAME
-
- MOV BX,OFFSET ENVIRONMENT ;Point to parameter block.
- MOV AX,4B00H ;Execute.
- INT 21H
- JNC CO_FOUND
-
- PUSH DS
- PUSH SI
- MOV DS,CS ;POINT TO CS
- MOV DI,OFFSET PATH_FOR_PGM ;MOVE WORK AREA
- MOV SI,SAVE_SI_PATH
- MOV DS,SAVE_DS_PATH
- LODSB ;LOAD PATH CHAR
- DEC SI
- CMP AL,00
- JNZ PATH_LOOP
- POP SI
- POP DS
- MOV DS,CS ;POINT TO CS
- MOV TEMPUS_RETCODE,4 ;SET RETURN CODE
- JMP CO1_RETURN
- PATH_LOOP: LODSB ;LOAD PATH CHAR
- CMP AL,';'
- JE ADD_CO_NAME_1
- CMP AL,00
- JE ADD_CO_NAME
- CO_NEXT: STOSB ;LOAD PATH CHAR
- JMP PATH_LOOP
- ADD_CO_NAME:
- DEC SI ;KEEP LAST CHAR ; OR x'00'
- ADD_CO_NAME_1:
- MOV AX,DS ;SAVE DS
- MOV BX,SI ;SAVE SI
- MOV DS,CS ;USE CS
- MOV SAVE_DS_PATH,AX ;SAVE ADDR OF PATH
- MOV SAVE_SI_PATH,BX ;SAVE ADDR OF PATH
- MOV SI,OFFSET LOAD_NAME_CO ;ADD CO NAME
- CALL MOVE_TEXT ;
- MOV BYTE PTR [DI],00 ;END OF NAME
- INC DI ;
- POP SI
- POP DS
- JMP TRY_AGAIN
-
- CO_FOUND: MOV AX,4D00H ;Get Return Code
- INT 21H
- MOV DI,OFFSET TEMPUS_RETCODE ;Load Return Code Addr
- STOSB
-
- CO1_RETURN: CLI
- MOV SP,CS:STACK_PTR ;Restore stack segment and pointer.
- MOV SS,CS:STACK_SEG
- STI
- POP ES ;Restore segment registers.
- POP DS
-
- MOV DX,80H ;Restore Disk Transfer Address.
- MOV AH,1AH
- INT 21H
- MOV BX,2000H ;Restore dual memory segments.
- MOV AH,4AH
- INT 21H
- CALL CLS ;Clear screen.
- ; CALL START_DISPLAY ;Restore menu.
- RET
-
- ;--------------------------------------------------------------------------;
- ; These six subroutines control the bar and page of the directory listing. ;
- ;--------------------------------------------------------------------------;
-
- UP_ARROW:
- ;----------------FW----------------------------------------------
- MOV BX,DIR_COUNT
- CMP BX,21
- JA UP_ARROW1
- MOV BX,LINE
- ADD BX,-160 ;Move bar up one line.
- CMP USE_DIRECTORY,32 ;IS THERE SPECIAL DIRECTORY NAME
- JE UP_ARROW_REG
- CMP BX,PAGE_START ;START OF LIST \ROOT +1
- JA UP_ARROW2
- JMP END_BAR
- UP_ARROW_REG: CMP BX,PAGE_START-160 ;START OF LIST \ROOT
- JA UP_ARROW2
- JMP END_BAR
- UP_ARROW1: MOV BX,CUR_OFFSET
- ADD BX,-160 ;Move bar up one line.
- CMP BX,OFFSET DIRECTORIES ;START OF LIST
- JAE UP_ARROW2
- MOV BX,LINE
- ADD BX,-160 ;Move bar up one line.
- CMP USE_DIRECTORY,32 ;IS THERE SPECIAL DIRECTORY NAME
- JE UP_ARROW_REG
- CMP BX,PAGE_START ;START OF LIST \ROOT +1
- JA UP_ARROW2
- JMP END_BAR
- ;----------------------------------------------------------------
- UP_ARROW2: MOV BP,-160 ;Move bar up one line.
- CALL SCROLL_BAR
- CALL SCROLL_TOP ;FW TOP CHECK
- RET
-
- DN_ARROW:
- ;----------------FW----------------------------------------------
- MOV BX,DIR_COUNT
- CMP BX,21
- JA DN_ARROW1
- MOV BX,LINE
- ADD BX,160
- CMP BX,PAGE_END ;AT LAST LINE
- JAE HOME_BAR
- JMP DN_ARROW2
-
- DN_ARROW1: MOV BX,CUR_OFFSET
- ADD BX,21*DIR_RECORD+160
- CMP BX,END_OFFSET ;AT LAST PAGE
- JB DN_ARROW2
- MOV BX,LINE
- ADD BX,160
- CMP BX,PAGE_END ;AT LAST LINE
- JAE HOME_BAR
- JMP DN_ARROW2
- ;----------------------------------------------------------------
- DN_ARROW2: MOV BP,160 ;Move bar down one line.
- CALL SCROLL_BAR
- RET
-
- PG_UP: MOV BP,-21*40 ;Move up 21 lines.
- CALL SCROLL
- JMP SHORT BOTTOM_BAR
-
- PG_DN: MOV BP,21*40 ;Move down 21 lines.
- MOVE_PAGE: CALL SCROLL
- JMP SHORT TOP_BAR ;Move bar to top.
-
- HOME_BAR: MOV CUR_OFFSET,OFFSET DIRECTORIES ;Move listing to beginning.
- TOP_BAR: MOV SI,PAGE_START ;And move bar to top.
- CALL MOVE_BAR
- CALL SCROLL_TOP ;FW TOP CHECK
- RET
-
- END_BAR: MOV BX,END_OFFSET ;Move listing to last page.
- SUB BX,21*DIR_RECORD
- CMP BX,OFFSET DIRECTORIES
- JBE BOTTOM_BAR
- MOV CUR_OFFSET,BX
- BOTTOM_BAR: MOV SI,PAGE_END ;And move bar to bottom.
- SUB SI,160
- CALL MOVE_BAR
- CALL SCROLL_TOP ;FW TOP CHECK
- RET
-
- ;-------------------------------------;
- ; FW MODIFICATION FOR NOT ROOT SHOWING;
- ;-------------------------------------;
- SCROLL_TOP: PUSH AX
- MOV AX,CUR_OFFSET ; WHAT CURRENT OFFSET
- CMP AX,OFFSET DIRECTORIES ; IS IT THE ROOT?
- JNZ SCROLL_TOP_END ; NO OUT
- MOV AL,CS:USE_DIRECTORY ;
- CMP AL,32 ; IS IT DIR TYPE?
- JZ SCROLL_TOP_END ; NO DON'T COMPARE
- MOV AX,BAR_START ; LOAD BAR TOP
- CMP AX,LINE ;BAR ON TOP LINE
- JNZ SCROLL_TOP_END ; NO OUT
- MOV BP,160 ;Move bar DOWN one line.
- CALL SCROLL_BAR
- SCROLL_TOP_END: POP AX
- RET
-
- ;----------------------------------------------;
- ; These subroutines support the ten functions. ;
- ;----------------------------------------------;
-
- CHMOD: MOV AX,4301H
- INT 21H
- RET
-
- ;--------------------------------------;
-
- DELAY: MOV AH,1
- INT 16H ;Loop here until keystroke.
- JZ DELAY
- CALL CLEAR_MSG
- RET
-
- ;-------------------------------------;
-
- DELETE: MOV DX,OFFSET DTA_AREA+30 ;Point to filename.
- ;DELETE: MOV DX,80H+30 ;Point to filename.
- MOV AH,41H
- INT 21H
- RET
-
- ;--------------------------------------;
-
- DO_ATTRIB: CALL FIRST_MATCH ;Find first file.
- NEXT_SET: MOV CL,DS:[80H+21] ;Get old attribute.
- AND CL,STRIP_MASK ;Strip request.
- OR CL,ADD_MASK ;Add request.
- XOR CH,CH ;Zero in high half.
- MOV DX,80H+30 ;Point to filename.
- CALL CHMOD ;And change the attribute.
- CALL NEXT_MATCHING ;Do it to all files.
- JNC NEXT_SET
- RET
-
- ;--------------------------------------;
-
- FIRST_MATCH: MOV DX,OFFSET STAR_DOT_STAR
- MOV CX,7
- MOV AH,4EH
- INT 21H
- RET
-
- NEXT_MATCHING: MOV AH,4FH
- INT 21H
- RET
- ;------------------------------------------------------;
- ; This subroutine gets a directory name from the user. ;
- ;------------------------------------------------------;
-
- BRQUERY:
- PUSH CX ;SAVE CX COUNT
- PUSH DI ;SAVE DI COUNT
- CALL DISPLAY_TEXT ;Display caller's message.
- INC DH ;Next row.
- CALL SET_CURSOR ;Move cursor.
- CALL CURSOR_ON ;Turn it on.
- POP DI ;SAVE DI COUNT
- POP CX ;SAVE CX COUNT
- PUSH CX ;SAVE CX COUNT
- PUSH DI ;SAVE DI COUNT
- MOV AX," "
- REP STOSB
- POP DI ;SAVE DI COUNT
- POP CX ;SAVE CX COUNT
- MOV BX,CX ;POINT TO LAST CHAR
- ADD CX,DI ;POINT TO LAST CHAR
- PUSH DI ;SAVE DI COUNT
-
- BRGET_QUERY: CALL READ_KEY ;Get a character.
- CMP AL,27 ;Is it Esc?
- JZ BRQUERY_DONT ;Is yes, exit subroutine.
- ; CMP AL,':' ;Ignore ":".
- ; JZ BRGET_QUERY
- CMP AL,13 ;Is it carriage return?
- JZ BRQUERY_DO ;If yes, return, do request.
- CMP AL,8 ;Is it backspace?
- JNZ BRNOT_BS ;If no, skip.
- CMP DI,BX ;At beginning of field?
- JZ BRGET_QUERY ;If yes, skip.
- DEC DI ;Else, decrement pointer.
- MOV SI,OFFSET BS ;Erase last character.
- CALL GET_TEXT
- JMP SHORT BRGET_QUERY
- BRNOT_BS: CMP AL,32 ;Is it above space?
- JB BRGET_QUERY ;If no, ignore.
- CMP DI,CX ;End of entry field?
- JZ BRGET_QUERY ;If yes, ignore.
- STOSB ;Else, store byte.
- CALL WRITE_TEXT ;And write it to screen.
- JMP SHORT BRGET_QUERY ;Get next keystroke.
-
- BRQUERY_DO:
- POP SI ;RESORE DI TO SI
- CMP DI,SI ;WAS ANOTHING ENTERED
- JE BRQUERY_DONT2 ;NO
- CALL CURSOR_OFF ;Turn it OFF
- CLC
- RET
-
- BRQUERY_DONT: POP SI
- BRQUERY_DONT2:
- CALL CURSOR_OFF ;Turn it OFF
- STC ;Indicate Esc was pressed.
- RET
-
- ;------------------------------------------------------;
- ; This subroutine gets a directory name from the user. ;
- ;------------------------------------------------------;
-
- QUERY: CALL DISPLAY_TEXT ;Display caller's message.
- MOV SI,DIR_NAME ;Add directory name.
- CALL GET_TEXT
- INC DH ;Next row.
- CALL SET_CURSOR ;Move cursor.
- CALL CURSOR_ON ;Turn it on.
- MOV DI,80H ;Write nulls over old entry.
- XOR AX,AX
- MOV CX,18
- REP STOSW
- MOV DI,80H ;Initiate pointer for entry.
-
- GET_QUERY: CALL READ_KEY ;Get a character.
- CMP AL,27 ;Is it Esc?
- JZ QUERY_DONT ;Is yes, exit subroutine.
- CMP AL,':' ;Ignore ":\?*".
- JZ GET_QUERY
- CMP AL,'\'
- JZ GET_QUERY
- CMP AL,'?'
- JZ GET_QUERY
- CMP AL,'*'
- JZ GET_QUERY
- CMP AL,13 ;Is it carriage return?
- JZ QUERY_DO ;If yes, return, do request.
- CMP AL,8 ;Is it backspace?
- JNZ NOT_BS ;If no, skip.
- CMP DI,80H ;At beginning of field?
- JZ GET_QUERY ;If yes, skip.
- DEC DI ;Else, decrement pointer.
- MOV SI,OFFSET BS ;Erase last character.
- CALL GET_TEXT
- JMP SHORT GET_QUERY
- NOT_BS: CMP AL,32 ;Is it above space?
- JBE GET_QUERY ;If no, ignore.
- CMP DI,8CH ;End of entry field?
- JZ GET_QUERY ;If yes, ignore.
- STOSB ;Else, store byte.
- CALL WRITE_TEXT ;And write it to screen.
- JMP SHORT GET_QUERY ;Get next keystroke.
-
- QUERY_DO: MOV BYTE PTR DS:[DI],0 ;Convert to ASCIIZ.
- CALL CURSOR_OFF ;Turn it OFF
- CLC
- RET
-
- QUERY_DONT:
- CALL CURSOR_OFF ;Turn it OFF
- STC ;Indicate Esc was pressed.
- RET
-
- ;--------------------------------------------;
- ; This subroutine gets a file count and ;
- ; displacement of the highlighted directory. ;
- ;--------------------------------------------;
-
- COUNT_THEM: MOV COUNT,0 ;Zero out file counter.
- MOV CLUST_COUNT,0 ;And cluster counter.
- MOV CLUST_COUNT_1_2MEG,0 ;And cluster counter.
- MOV CLUST_COUNT_1_4MEG,0 ;And cluster counter.
- MOV CLUST_COUNT_360K,0 ;And cluster counter.
- MOV DISKS_1_2MEG,0 ;DISK counter.
- MOV DISKS_1_4MEG,0 ;DISK counter.
- MOV DISKS_360K,0 ;DISK counter.
- CALL FIRST_MATCH ;Get first file.
- JC DISPLAY_COUNT
-
- FIND_NEXT: INC COUNT ;Increment file count.
- ;-----------------------FW---------------------------------------------
- MOV AX,DS:[DTA_AREA+26] ;Retrieve low word
- MOV DX,DS:[DTA_AREA+28] ; and high word of file size.
- ADD AX,128 ;128 BYTES ADDED BY BACKUP
- DIV CLUST_BYTES_1_2MEG ;Divide to get cluster count 1.2MEG
- OR DX,DX ;If remainder, increment count.
- JZ NO_REM_1_2MEG
- INC CLUST_COUNT_1_2MEG
- NO_REM_1_2MEG: ADD CLUST_COUNT_1_2MEG,AX ;Add cluster count.
-
- MOV AX,DS:[DTA_AREA+26] ;Retrieve low word
- MOV DX,DS:[DTA_AREA+28] ; and high word of file size.
- ADD AX,128 ;128 BYTES ADDED BY BACKUP
- DIV CLUST_BYTES_1_4MEG ;Divide to get cluster count 1.2MEG
- OR DX,DX ;If remainder, increment count.
- JZ NO_REM_1_4MEG
- INC CLUST_COUNT_1_4MEG
- NO_REM_1_4MEG: ADD CLUST_COUNT_1_4MEG,AX ;Add cluster count.
-
- MOV AX,DS:[DTA_AREA+26] ;Retrieve low word
- MOV DX,DS:[DTA_AREA+28] ; and high word of file size.
- ADD AX,128 ;128 BYTES ADDED BY BACKUP
- DIV CLUST_BYTES_360K ;Divide to get cluster count 360K
- OR DX,DX ;If remainder, increment count.
- JZ NO_REM_360K
- INC CLUST_COUNT_360K
- NO_REM_360K: ADD CLUST_COUNT_360K,AX ;Add cluster count.
-
- ;----------------------------------------------------------------------
- MOV AX,DS:[DTA_AREA+26] ;Retrieve low word
- MOV DX,DS:[DTA_AREA+28] ; and high word of file size.
- DIV CLUST_BYTES ;Divide to get cluster count.
- OR DX,DX ;If remainder, increment count.
- JZ NO_REMAINDER
- INC CLUST_COUNT
- NO_REMAINDER: ADD CLUST_COUNT,AX ;Add cluster count.
- CALL NEXT_MATCHING ;Find rest of files.
- JNC FIND_NEXT
-
- DISPLAY_COUNT: MOV DX,1629H ;Row 21; column 41.
- CALL SET_CURSOR
- CALL GET_COUNT ;Display count.
- MOV SI,OFFSET FILE_COUNT ;And message.
- CALL GET_TEXT
- MOV SI,DIR_NAME ;Display parent directory.
- CALL GET_TEXT
- MOV SI,OFFSET USING ;Display rest of message.
- CALL GET_TEXT
- MOV AX,CLUST_COUNT ;Retrieve cluster count.
- XOR DX,DX ;Zero in high half.
- MOV BX,CLUST_BYTES
- MUL BX ;Multiply to get total bytes.
- MOV BX,1024
- DIV BX ;Divide by one K bytes.
- MOV COUNT,AX
- CALL GET_COUNT ;Convert count to ASCII.
- MOV AL,'K' ;Tack on "K".
- CALL WRITE_TEXT
- ;-----------------------FW---------------------------------------------
- XOR DX,DX ;Zero in high half.
- MOV AX,CLUST_COUNT_1_2MEG ;CNT OF 1.2MEG CLUSTERS USED
- DIV CLUSTERS_1_2MEG ;Divide to get NO DISKS
- OR DX,DX ;If remainder, increment count.
- JZ NO_REM_1_2MEG_D
- INC DISKS_1_2MEG
- NO_REM_1_2MEG_D: ADD DISKS_1_2MEG,AX ;Add DISK count.
- XOR DX,DX ;Zero in high half.
- MOV AX,CLUST_COUNT_1_4MEG ;CNT OF 1.4MEG CLUSTERS USED
- DIV CLUSTERS_1_4MEG ;Divide to get NO DISKS
- OR DX,DX ;If remainder, increment count.
- JZ NO_REM_1_4MEG_D
- INC DISKS_1_4MEG
- NO_REM_1_4MEG_D: ADD DISKS_1_4MEG,AX ;Add DISK count.
- XOR DX,DX ;Zero in high half.
- MOV AX,CLUST_COUNT_360K ;CNT OF 360K CLUSTERS USED
- DIV CLUSTERS_360K ;Divide to get NO DISKS
- OR DX,DX ;If remainder, increment count.
- JZ NO_REM_360K_D
- INC DISKS_360K
- NO_REM_360K_D: ADD DISKS_360K,AX ;Add DISK count.
- MOV AX,COUNT
- PUSH AX ;SAVE COUNT
- MOV DX,1629H ;Row 22; column 41.
- CALL SET_CURSOR
- MOV SI,OFFSET BACKUP_USES ;DISPLAY MESSAGE
- CALL GET_TEXT
- MOV AX,DISKS_1_2MEG
- MOV COUNT,AX ;1.2MEG COUNT
- CALL GET_COUNT ;Display count.
- MOV SI,OFFSET BACKUP_USES_1_2MEG ;DISPLAY MESSAGE
- CALL GET_TEXT
-
- MOV DX,1729H ;Row 23; column 41.
- CALL SET_CURSOR
- MOV SI,OFFSET BACKUP_USES ;DISPLAY MESSAGE
- CALL GET_TEXT
- MOV AX,DISKS_1_4MEG
- MOV COUNT,AX ;360K COUNT
- CALL GET_COUNT ;Display count.
- MOV SI,OFFSET BACKUP_USES_1_4MEG ;DISPLAY MESSAGE
- CALL GET_TEXT
-
- MOV DX,1829H ;Row 23; column 41.
- CALL SET_CURSOR
- MOV SI,OFFSET BACKUP_USES ;DISPLAY MESSAGE
- CALL GET_TEXT
- MOV AX,DISKS_360K
- MOV COUNT,AX ;360K COUNT
- CALL GET_COUNT ;Display count.
- MOV SI,OFFSET BACKUP_USES_360K ;DISPLAY MESSAGE
- CALL GET_TEXT
- POP AX
- MOV COUNT,AX ;SAVE COUNT
- ;----------------------------------------------------------------------
- RET
-
- ;------------------------------------------------------;
- ; This subroutine displays the loading message and ;
- ; reads the disk on reads requested from command line. ;
- ;------------------------------------------------------;
-
- FIRST_READ: CALL CLS
- MOV DX,0C18H
- MOV SI,OFFSET LOADING
- CALL DISPLAY_TEXT
-
- ;-------------------------------------------------------------------;
- ; This subroutine reads the root directory and FAT from disk. ;
- ; Then finds subdirectories stacking them in the database one level ;
- ; at a time. Finally, the database is alphabetized by level. ;
- ;-------------------------------------------------------------------;
-
- READ_DATA: MOV AX,DISK_BLOCK[2] ;Retrieve bytes per sector.
- MOV BL,BYTE PTR DISK_BLOCK[4] ;And sectors per cluster -1.
- INC BL ;Adjust.
- XOR BH,BH ;Zero high byte.
- MOV CLUST_SECTORS,BX ;And save.
- MUL BX ;Get total bytes per cluster.
- MOV CLUST_BYTES,AX ;And save.
- MOV CX,32 ;Divide by bytes per directory.
- DIV CX
- MOV CLUST_RECORDS,AX ;And save.
-
- GET_ROOT: MOV AX,DISK_BLOCK[9] ;Retrieve number of root entries.
- MOV CX,32 ;Times 32 byte record length.
- MUL CX
- JNC NO_ERROR ;Problem if carry.
- DISK_EXIT: MOV DX,OFFSET UNKNOWN ;Display message and exit.
- ERROR_EXIT: CALL RESTORE_DRIVE
- MSG_EXIT: MOV AH,9
- INT 21H
- CALL CURSOR_ON
- INT 20H
-
- NO_ERROR: MOV BX,DISK_BLOCK[2] ;Divide by bytes per sector.
- DIV BX
- MOV ROOT_SECTORS,AX ;That's root length in sectors.
- MOV CX,AX ;Root length.
- MOV DX,DISK_BLOCK[16] ;Directory starting sector.
- MOV BX,OFFSET ROOT_DIRECTORY ;Read the root directory.
- CALL READ_DISK
-
- MOV AX,DATA_SEGMENT ;Get data storage segment.
- MOV ES,AX
- XOR BP,BP ;Tree level counter.
- XOR BX,BX ;Entry number counter.
- MOV SI,OFFSET ROOT_DIRECTORY ;Point to root directory.
- MOV DI,OFFSET DATA_BUFFER ;Point to database storage.
- MOV BYTE PTR ES:[DI],0FFH ;Initialize with end signature.
- MOV ES:LEVEL_ADDRESS,DI ;Store starting level address.
- MOV CX,DISK_BLOCK[9] ;Retrieve no. root directories.
- CALL STORE_RECORD ;Store them in database.
- CMP BX,0 ;BX returns with no. entries.
- JZ DATA_END ;If none, done here.
-
- GET_FAT: PUSH BX ;Save entry count.
- MOV AL,BYTE PTR DISK_BLOCK[15] ;Retrieve sectors for FAT.
- XOR AH,AH ;Zero in high byte.
- MOV CX,AX ;Save.
- MOV BX,DISK_BLOCK[2] ;Retrieve byte per sector.
- MUL BX ;Multiply to get total bytes.
- JC DISK_EXIT ;Problem if carry.
- CMP AX,65535-8192 ;Too big if over 56K.
- JA DISK_EXIT ;Display message and exit.
- MOV DX,DISK_BLOCK[6] ;Retrieve reserved sectors.
- MOV BX,OFFSET FAT ;Read the FAT.
- CALL READ_DISK
- JC ERROR_EXIT ;Exit if problem.
-
- POP BX ;Retrieve directory count.
- MOV AX,DATA_SEGMENT ;Point to database segment.
- MOV ES,AX
- MOV SI,OFFSET DATA_BUFFER ;And point to database offset.
- UP_LEVEL: INC BP ;Bump point to next level.
- INC BP
- MOV ES:[OFFSET LEVEL_ADDRESS+BP],DI ;Save level address.
- MOV CX,BX ;Retrieve record count.
- XOR BX,BX ;Zero out entry counter.
- NEXT_SECTOR: MOV DX,ES:[SI+16] ;Retrieve starting cluster.
-
- NEXT_CLUSTER: MOV LAST_CLUSTER,DX ;And save.
- PUSH CX ;Save some registers.
- PUSH BX
- CALL READ_CLUSTER ;Retrieve directory sector.
- POP BX
- MOV DX,ES:[SI+1] ;Retrieve parent entry number.
- PUSH SI
- MOV SI,OFFSET WORKSPACE ;Point to new directory.
- MOV CX,CLUST_RECORDS ;Retrieve records per cluster.
- CALL STORE_RECORD ;Store subdirectories in database.
- POP SI
- POP CX
- JC END_LEVEL ;If carry, last entry found.
- CALL CK_FAT ;Else, get next cluster.
- JNC NEXT_CLUSTER ;If carry, last cluster found.
-
- END_LEVEL: ADD SI,DATA_RECORD ;Else, point to next root entry.
- LOOP NEXT_SECTOR ;Find next subdirectory.
- CMP SI,DI ;Did we find any at this level?
- JNZ UP_LEVEL ;If yes, continue.
- MOV AX,0FFFFH ;Else, done; mark with signature.
- STOSB
- MOV ES:[OFFSET LEVEL_ADDRESS+BP+2],AX ;Mark level address.
- CALL SORT ;Alphabetize by level.
- DATA_END: PUSH CS ;Restore segment registers.
- PUSH CS
- POP DS
- POP ES
- RET
-
- ;-------------------------------------------------;
- ; This subroutine does the direct sector reading. ;
- ;-------------------------------------------------;
-
- READ_DISK: PUSH BP ;Call destroys all registers
- PUSH SI ; except segment registers
- PUSH DI ; so we have to preserve.
- PUSH DS
-
- MOV AL,DRIVE ;Retrieve drive.
- MOV SI,DS ;Point to second segment.
- ADD SI,1000H
- MOV DS,SI
- INT 25H ;Read the sectors.
- POP AX ;Get rid off flags left on stack.
-
- POP DS ;Restore registers.
- POP DI
- POP SI
- POP BP
- RET
-
- ;----------------------------------------;
- ; This subroutine will read CX clusters. ;
- ;----------------------------------------;
-
- READ_CLUSTER: MOV AX,LAST_CLUSTER ;Retrieve cluster number.
- MOV CX,CLUST_SECTORS ;Retrieve sectors per cluster.
- MUL CX ;Multiply to get sector start.
- MOV DX,AX
- ADD DX,DISK_BLOCK[11] ;Add start of first data cluster.
- SUB DX,CX ;Subtract to reflect cluster
- SUB DX,CX ; 2 as first logical data sector.
- MOV BX,OFFSET WORKSPACE ;Point to workspace.
- CALL READ_DISK ;And get data.
- RET
-
- ;------------------------------------------------------------------;
- ; This subroutine stores the level number, entry number, parent ;
- ; entry number, the directory name and attribute byte in database. ;
- ;------------------------------------------------------------------;
-
- STORE_RECORD: PUSH DS ;Point to second segment.
- MOV AX,CS
- ADD AX,1000H
- MOV DS,AX
-
- NEXT_RECORD: CMP BYTE PTR [SI],0 ;No more entries?
- JZ STORE_RETURN ;If yes, done here.
- TEST BYTE PTR [SI+11],10H ;Is it a directory?
- JZ LOOP_STORE ;If no, next entry.
- CMP BYTE PTR [SI],0E5H ;Is it a removed directory?
- JZ LOOP_STORE ;If yes, skip.
- CMP BYTE PTR [SI],'.' ;Is it a dot or dot-dot entry?
- JZ LOOP_STORE ;If yes, skip.
- ;---------------------------------------------------------------------
- ; FW MOD CHECK FOR ONLY THE DIRECTORY IN PARM
- ;---------------------------------------------------------------------
- MOV AL,CS:USE_DIRECTORY ; 1ST CHAR
- CMP AL,32 ; IS DIR BLANK?
- JZ NOT_ROOT ; YES DON'T COMPARE
- CMP BP,0 ; IS IT THE ROOT?
- JNZ NOT_ROOT ; NO DON'T COMPARE
- PUSH CX
- PUSH SI
- PUSH DI
- MOV DI,OFFSET USE_DIRECTORY
-
- MOV CX,11 ; COUNT FOR COMPARE
- REPE CMPSB
- POP DI
- POP SI
- POP CX
- JNZ LOOP_STORE ; NOT EQUAL BYPASS
- ;---------------------------------------------------------------------
- NOT_ROOT: PUSH SI
- MOV AX,BP ;Store level number.
- STOSB
- MOV AX,BX ;Store entry number.
- STOSW
- MOV AX,DX ;Store parent entry number.
- STOSW
- PUSH CX
- MOV CX,11 ;Store 11 bytes of name.
- REP MOVSB
- POP CX
- ADD SI,15 ;Store starting cluster.
- MOVSW
- INC BX ;Increment entry count.
- POP SI
- XOR AX,AX ;Assume not a hidden directory.
- TEST BYTE PTR [SI+11],2 ;Is it hidden?
- JZ STORE_ATTRIB ;If no, store null.
- MOV AX,'H' ;Else, store "H".
- STORE_ATTRIB: STOSW
-
- LOOP_STORE: ADD SI,32 ;Point to next entry.
- LOOP NEXT_RECORD
- POP DS ;Restore segment.
- CLC ;Indicate full sector.
- RET
-
- STORE_RETURN: POP DS ;Indicate not full sector.
- STC
- RET
-
- ;-------------------------------------------------------------------;
- ; This subroutine finds the next cluster in the chain from the FAT. ;
- ;-------------------------------------------------------------------;
-
- CK_FAT: PUSH ES ;Save some registers.
- PUSH BX
- PUSH CX
- MOV AX,CS ;Point to second segment.
- ADD AX,1000H
- MOV ES,AX
-
- MOV AX,LAST_CLUSTER ;Retrieve last cluster.
- PUSH AX ;Save.
- XOR DX,DX ;Zero in high half.
- MOV BX,DISK_BLOCK[13]
- CMP BX,0FF6H ;Number of clusters above 4085?
- JA SIXTEEN_BIT ;If yes, 16 bit FAT.
- TWELVE_BIT: MOV BX,15 ;Else, 12 bit FAT.
- MUL BX ;Multiply by 1.5 (or 15/10).
- MOV BX,10
- DIV BX
- MOV BX,AX
- MOV DX,ES:FAT[BX] ;Retrieve cluster pointer.
- POP AX ;Retrieve last cluster.
- TEST AX,1 ;Was last cluster even number?
- JZ LOW_ORDER ;If yes, use low order 12 bits.
- MOV CL,4 ;Else, high order 12 bits.
- SHR DX,CL ;Shift right 4 bits.
- JMP SHORT CK_12BIT
- LOW_ORDER: AND DX,0000111111111111xB ;Mask off top 4 bits.
- CK_12BIT: CMP DX,0FF8H ;Is it end of chain?
- JAE CLUSTER_END ;If yes, indicate so.
- JMP SHORT RETURN_CLUST ;Else, return with cluster in DX.
-
- SIXTEEN_BIT: POP BX ;Retrieve last cluster.
- SHL BX,1 ;Multiply by 2.
- MOV DX,ES:FAT[BX] ;Retrieve next cluster number.
- CMP DX,0FFF8H ;Is it end of chain?
- JAE CLUSTER_END ;If yes, indicate so.
-
- RETURN_CLUST: POP CX ;Restore registers.
- POP BX
- POP ES
- CLC ;Indicate not end of chain.
- RET
-
- CLUSTER_END: POP CX
- POP BX
- POP ES
- STC ;Indicate end of cluster chain.
- RET
-
- ;--------------------------------------------------------;
- ; This subroutine alphabetizes the directories by level. ;
- ;--------------------------------------------------------;
-
- SORT: PUSH DS
- MOV AX,DATA_SEGMENT ;Point to database segment.
- MOV ES,AX
- MOV DS,AX
- XOR BP,BP ;Zero in level pointer.
- LEVEL_SORT: MOV DX,ES:[OFFSET LEVEL_ADDRESS+BP+2] ;Retreive level offset.
- CMP DX,0FFFFH ;End signature?
- JZ SORT_RETURN ;If yes, done here.
- SUB DX,DATA_RECORD ;Point to end of lower level.
- PUSH BP ;Save level pointer.
-
- NEXT_PASS: POP BP
- PUSH BP
- MOV BX,ES:[OFFSET LEVEL_ADDRESS+BP] ;Point to start of level.
- XOR BP,BP ;Zero in exchange flag.
- CMP BX,DX ;End of level?
- JZ SORT_SET ;If yes, next level.
-
- NEXT_SORT: MOV SI,BX ;Source and destination.
- ADD SI,5 ;Point to name
- MOV DI,BX ; in each record.
- ADD DI,DATA_RECORD+5
- MOV CX,11
- REPZ CMPSB ;Compare names.
- JBE END_SORT ;If already in order, skip.
-
- MOV SI,BX ;Else, recover pointers.
- MOV DI,BX
- ADD DI,DATA_RECORD
- MOV CX,DATA_RECORD/2 ;Exchange the records.
- NEXT_SWAP: MOV AX,[DI]
- MOVSW
- MOV [SI-2],AX
- LOOP NEXT_SWAP
- MOV BP,1 ;Flag that exchange was made.
-
- END_SORT: ADD BX,DATA_RECORD ;Point to next record.
- CMP BX,DX ;End of top?
- JB NEXT_SORT ;If no, bubble sort next.
- SUB DX,DATA_RECORD ;Else, move top down one record.
- CMP BP,0 ;Was there exchange made?
- JNZ NEXT_PASS
-
- SORT_SET: POP BP
- INC BP ;Next level.
- INC BP
- JMP SHORT LEVEL_SORT ;Sort it.
-
- SORT_RETURN: POP DS ;Restore data segment.
- RET
-
- ;-------------------------------------------------------------;
- ; This subroutine formats the database into a directory tree. ;
- ;-------------------------------------------------------------;
-
- FORMAT_IT: PUSH DATA_SEGMENT ;Point to database segment.
- POP DS
- MOV AX,CS ;Point to second segment.
- ADD AX,1000H
- MOV ES,AX
- MOV SI,OFFSET LEVEL_ADDRESS ;Move resident database
- MOV DI,SI ; into our second segment.
- MOV CX,100+(DATA_RECORD*500/2)
- REP MOVSW
-
- PUSH CS ;Restore segment registers.
- PUSH CS
- POP DS
- POP ES
- CALL STORE_ROOT ;Initialize with "\ (ROOT)".
-
- XOR BP,BP ;Zero in level pointer.
- MOV SI,OFFSET DATA_BUFFER ;Point to database.
- MOV DI,OFFSET DIRECTORIES+DIR_RECORD+1 ;Point to storage.
- MOV LAST_ENTRY,DI ;Save current entry.
- MOV AX,CS ;Point to second segment.
- ADD AX,1000H
- MOV DS,AX
- CMP BYTE PTR [SI],0FFH ;No subs signature?
- JZ SKIP_FORMAT ;If yes, skip format.
-
- NEXT_FORMAT: CALL STORE_NAME ;Format the directory name.
- ADD SI,DATA_RECORD ;Point to next record.
- CMP BYTE PTR [SI],0 ;End of root directory?
- JZ NEXT_FORMAT ;If no, get next entry.
- SKIP_FORMAT: PUSH CS ;Else, done.
- POP DS ;Restore data segment.
- DEC DI ;Adjust end pointer.
- MOV END_OFFSET,DI ;And save.
- MOV BX,DIR_COUNT ;Retrieve directory count.
- CMP BX,21 ;Enough to fill one page?
- JAE FORMAT_END ;If yes, use default setting.
- MOV AX,160 ;Calculate last record.
- MUL BL
- ADD AX,PAGE_START ;Add bar offset.
- MOV PAGE_END,AX ;And save.
- FORMAT_END: RET
-
- ;------------------------------------------------------;
- ; This subroutine initializes the directory tree image ;
- ; with nulls and makes the first record "\ (ROOT)". ;
- ;------------------------------------------------------;
-
- STORE_ROOT: MOV AX,0
- MOV DI,OFFSET DIRECTORIES
- MOV CX,30000 / 2
- REP STOSW
-
- MOV DI,OFFSET DIRECTORIES
- MOV SI,OFFSET ROOT
- MOV CX,8
- REP MOVSB
- RET
-
- ;-----------------------------------------------------------;
- ; This subroutine recursively builds the subdirectory tree. ;
- ;-----------------------------------------------------------;
-
- STORE_NAME: PUSH SI ;Save a couple registers.
- PUSH BP
-
- PUSH DI ;Save pointers.
- PUSH SI
- PUSH SI
- MOV SI,CS:LAST_ENTRY ;Retrieve last entry.
- MOV DX,DI ;Retrieve current position.
- CMP SI,DX ;Have stored any subdirectories?
- JZ STORE_DIR ;If no, skip tree structuring.
- MOV BYTE PTR CS:[SI+BP],195 ;Store connecting T character.
- PLACE_BAR: ADD SI,DIR_RECORD ;Move to next record.
- CMP SI,DX ;Are we at the current record?
- JZ STORE_DIR ;If yes, done here.
- MOV BYTE PTR CS:[SI+BP],179 ;Else, store vertical line char.
- JMP SHORT PLACE_BAR ;Repeat until up to date.
-
- STORE_DIR: MOV CS:LAST_ENTRY,SI ;Store current position.
- POP SI ;Restore current record pointer.
- INC CS:DIR_COUNT ;Increment directory counter.
- ADD DI,BP ;Add level pointer.
- MOV AL,192 ;Store L line character.
- STOSB
- MOV AL,196 ;Store horizontal line character.
- STOSB
- ADD SI,5 ;Point to directory name.
- MOV CX,8
- CALL STORE_BYTES ;And store in tree.
- CMP BYTE PTR [SI],32
- JZ END_NAME
- MOV AL,'.' ;If exists, append extension.
- STOSB
- MOV CX,3
- CALL STORE_BYTES
- END_NAME: POP SI ;Restore current record pointer.
- INC DI ;Bump pointer for space.
- MOV AL,[SI+18] ;Retrieve "hidden" field.
- STOSB ;And store it.
- NEXT_DEST: POP DI ;Restore destination pointer.
- ADD DI,DIR_RECORD ;Point to next tree record.
-
- PUSH CS:LAST_ENTRY ;Save current position pointer.
- MOV CS:LAST_ENTRY,DI ;Save our current position.
- INC BP ;Bump pointer to next level.
- INC BP
- MOV BX,DS:[OFFSET LEVEL_ADDRESS+BP] ;Get level offset.
-
- NEXT_SUB: MOV AL,DS:[BX] ;Retrieve level pointer.
- XOR AH,AH
- CMP AX,BP ;Is it our level?
- JA STORE_END ;If next level, done here.
- MOV AX,DS:[BX+3] ;Retrieve parent entry number.
- CMP AX,DS:[SI+1] ;Is it our entry number?
- JNZ SKIP_SUB ;If no, check next record.
-
- GET_SUB: PUSH BX ;Else, save pointers.
- PUSH SI
- MOV SI,BX ;Point to our offset.
- CALL STORE_NAME ;Store subdirectory.
- POP SI ;Restore pointers.
- POP BX
-
- SKIP_SUB: ADD BX,DATA_RECORD ;Next record.
- JMP SHORT NEXT_SUB
-
- STORE_END: POP CS:LAST_ENTRY ;Restore last entry pointer.
- POP BP
- POP SI
- RET
-
- ;--------------------------------------;
-
- STORE_BYTES: LODSB ;Store all non space name
- CMP AL,32 ; characters.
- JZ SKIP_STORE
- STOSB
- SKIP_STORE: LOOP STORE_BYTES
- RET
-
- ;-----------------------------------------------------------------;
- ; This subdirectory works its way back to the root directory from ;
- ; the currently highlighted directory and then retraces back up ;
- ; the tree changing the default directory one level at a time. ;
- ;-----------------------------------------------------------------;
-
- NEW_DIR: MOV COUNT,0 ;Zero out path counter.
- MOV DX,OFFSET ROOT_DIR ;Change to root directory.
- CALL CD
- XOR CX,CX ;Zero in level counter.
- MOV DI,CUR_RECORD ;Point to highlighted record.
- CMP DI,OFFSET DIRECTORIES ;Is it the root?
- JZ NEW_DIR_END ;If yes, done here.
- MOV BX,DIR_NAME ;Point to directory name.
- DEC BX ;Point to horizontal character.
-
- NEXT_SUBDIR: MOV SI,BX
- FIND_DIR: LODSB ;Get a byte.
- CMP AL,196 ;Is it horizonatal character?
- JNZ FIND_DIR ;If no, find it.
- PUSH SI ;Save directory.
- INC CX ;Also keep track of level.
- NEXT_PATH: INC COUNT ;Increment path length.
- LODSB
- CMP AL,0 ;Are we at end of directory name?
- JNZ NEXT_PATH ;If no, find it.
- CMP BYTE PTR [DI+2],196 ;Is there a level under us?
- JZ CHANGE_THEM ;If no, done here.
- DEC BX ;Else, decrement level pointer.
- DEC BX
- NEXT_LEVEL: SUB DI,DIR_RECORD ;Look for next lower level.
- SUB BX,DIR_RECORD
- CMP BYTE PTR [BX],196 ;Have we found parent record?
- JNZ NEXT_LEVEL ;If no, find it.
- JMP SHORT NEXT_SUBDIR ;And find name and length.
-
- CHANGE_THEM: POP DX ;Retrieve directory name pointer.
- CALL CD ;Change directories.
- JC RESTORE_STACK ;If nonexistant, restore stack
- LOOP CHANGE_THEM ;Else, continue up the tree.
- NEW_DIR_END: RET
-
- NEXT_STACK: POP DX ;If error, restore stack
- CALL BEEP ;Change directories.
- CALL BEEP ;Change directories.
- CALL BEEP ;Change directories.
- RESTORE_STACK: LOOP NEXT_STACK ; before returning.
- RET
-
- ;--------------------------------------;
-
- CD: MOV AH,3BH
- INT 21H
- RET
-
- ;--------------------------------------------------;
- ; This subroutine finds the highlighted directory. ;
- ;--------------------------------------------------;
-
- GET_NAME: MOV SI,CUR_OFFSET ;Get top of page.
- MOV AX,LINE ;Get location of bar.
- SUB AX,PAGE_START ;Adjust.
- MOV CL,160 ;80 characters + 80 attributes.
- DIV CL ;Divide to get line number.
- MOV CL,DIR_RECORD ;Times directory record length.
- MUL CL
- ADD SI,AX ;Add to current offset.
- MOV CUR_RECORD,SI ;And save pointer.
- CMP CUR_RECORD,OFFSET DIRECTORIES ;Is it top line?
- JZ NAME_RETURN ;If yes, done here.
- FIND_TOP: LODSB
- CMP AL,196 ;Is it the horizontal line char?
- JNZ FIND_TOP ;If no, find it.
- NAME_RETURN: MOV DIR_NAME,SI ;And store name pointer.
- MOV AX,SI
- SUB AX,CUR_RECORD ;CALC LEVEL OF DIR
- MOV CUR_LEVEL,AX ;AND SAVE
- RET
-
- ;----------------------------------------------------------;
- ; This subdirectory searches through the graphic tree for ;
- ; the name of the DOS default directory and highlights it. ;
- ;----------------------------------------------------------;
-
- GET_CURRENT: MOV SI,OFFSET CURRENT_DIR ;Point to default directory.
- MOV BYTE PTR [SI],'\' ;DOS fails to include starting "\".
- INC SI ;Point to first level.
- MOV DL,DRIVE ;Retrieve drive.
- INC DL ;Convert to DOS format.
- MOV AH,47H ;Retrieve current directory.
- INT 21H
- CALL CAPITALIZE ;Capitalize it.
-
- MOV BX,OFFSET CURRENT_DIR+1 ;Point to default directory.
- CMP BYTE PTR [BX],0 ;Are we at end?
- JZ CURRENT_END ;If yes, done here.
- MOV BP,OFFSET DIRECTORIES+DIR_RECORD+3 ;Store pointer.
- XOR DX,DX ;Zero entry counter.
- MOV CX,500 ;Search a maximum of 500 records.
-
- NEXT_DEFAULT: INC DX ;Increment entry counter.
- MOV SI,BX ;Point to default directory.
- MOV DI,BP ;Point to directory tree.
- CMP BYTE PTR [DI-1],196 ;Is it horizontal bar?
- JNZ NO_MATCH ;If no, next record.
- NEXT_MATCH: CMP BYTE PTR [DI],0 ;Is it end of tree name?
- JNZ CK_DEFAULT ;If no, see if name matches.
- CMP BYTE PTR [SI],'\' ;Is it end of default level?
- JZ MATCH ;If yes, then we have a match.
- CMP BYTE PTR [SI],0 ;Zero also marks name end.
- JZ MATCH
- CK_DEFAULT: CMPSB ;Character in name match?
- JZ NEXT_MATCH ;If yes, check next byte.
- NO_MATCH: ADD BP,DIR_RECORD ;Else, next record.
- LOOP NEXT_DEFAULT ;Search up to 500 records.
- JMP SHORT CURRENT_END ;Give up if not found.
-
- MATCH: DEC CX ;Decrement search counter.
- JZ CURRENT_END ;Exit, if not found.
- INC SI ;Point to name.
- MOV BX,SI ;Store current level.
- ADD BP,DIR_RECORD+2 ;Point to next record and level.
- CMP BYTE PTR [SI-1],0 ;End of default?
- JNZ NEXT_DEFAULT ;If no, continue.
-
- FIND_DEFAULT: MOV CX,DIR_COUNT ;Retrieve directory count.
- SUB CX,DX ;Subtract default entry counter.
- MOV SEARCH_COUNT,CX ;Save.
- MOV CL,ATTR_TREE ;Turn off bar for now.
- MOV BAR_ATTRIBUTE,CL
- CALL END_BAR ;First move to end.
- JMP SHORT FIND_IT
- NEXT_FIND: CALL UP_ARROW2 ;Move up to matching directory.
- FIND_IT: DEC SEARCH_COUNT
- JNZ NEXT_FIND
- MOV CL,INVERSE ;Turn bar back on.
- MOV BAR_ATTRIBUTE,CL
- CURRENT_END: RET
-
- ;-----------------------------------------------------;
- ; This subroutine displays the menu, requested drive, ;
- ; and directory count. Also displays highlight bar. ;
- ;-----------------------------------------------------;
-
- START_DISPLAY:
- MOV SI,OFFSET MENU ;Point to menu position.
- CMP DEFAULT_MENU,1
- JE LONG_MENU
- MOV SI,OFFSET MENU2 ;Point to menu2 position.
- LONG_MENU: MOV DI,(1*160)+98 ;And to screen position.
- MOV BH,MENU_LGTH ;Display 19 lines of menu.
- NEXT_FUNCTION:
- MOV CX,MENU_WIDTH ;22 characters per line.
- NEXT_MENU:
-
- LODSB
- MOV BL,AL
- CALL WRITE_SCREEN
- ;----------------------FW--------------------------------------
- MOV BL,ATTR_MENU ;<<<<<<
- DEC DI
- CALL WRITE_SCREEN
- DEC DI
- ;----------------------FW--------------------------------------
- LOOP NEXT_MENU
-
- MOV BL,ATTR_TREE ;<<<<<<
-
- ADD DI,160-(MENU_WIDTH*2) ;Next line.
- DEC BH
- JNZ NEXT_FUNCTION
-
- MOV SI,OFFSET HEADING ;Display "Directories of drive".
- MOV DX,1
- CALL DISPLAY_TEXT
- MOV AL,DRIVE
- ADD AL,'A' ;Display drive.
- CALL WRITE_TEXT
- MOV AL,':' ;And colon.
- CALL WRITE_TEXT
- CALL COUNT_DIRS ;Display directory count.
- MOV SI,LINE
- CALL MOVE_BAR ;Highlight the current directory.
- ;--------------FW CHANGE---------------------------------------------
- CALL SCROLL_TOP ;DON'T POINT AT ROOT
- ;--------------------------------------------------------------------
- RET
-
- ;----------------------------------------------------;
- ; This subroutine capitalizes the default directory. ;
- ;----------------------------------------------------;
-
- CAPITALIZE: CMP BYTE PTR [SI],'a'
- JB NEXT_CAPS
- CMP BYTE PTR [SI],'z'
- JA NEXT_CAPS
- AND BYTE PTR [SI],5FH
- NEXT_CAPS: INC SI
- CMP BYTE PTR [SI],0
- JNZ CAPITALIZE
- RET
-
- ;-------------------------------------;
- ; This subroutine scrolls the screen. ;
- ;-------------------------------------;
-
- SCROLL: MOV SI,CUR_OFFSET ;Get current offset.
- ADD SI,BP ;Add requested direction.
- CK_LOWER: CMP SI,OFFSET DIRECTORIES ;If above start check uppe limit.
- JAE UPPER_LIMIT
- LOWER_LIMIT: MOV CUR_OFFSET,OFFSET DIRECTORIES ;Else, make it start.
- JMP SHORT SCROLL_RETURN ;And update screen.
-
- UPPER_LIMIT: MOV BX,END_OFFSET ;See if beyond end of
- CMP BX,OFFSET DIRECTORIES+21*DIR_RECORD ; directory listing.
- JA CK_UPPER
- MOV CUR_OFFSET,OFFSET DIRECTORIES
- MOV AT_LAST_LINE,"=" ;SAY AT LAST LINE
- JMP SHORT SCROLL_RETURN
-
- CK_UPPER: SUB BX,21*DIR_RECORD
- CMP SI,BX
- JBE END_SCROLL
- MOV AT_LAST_LINE,"=" ;SAY AT LAST LINE
- MOV SI,BX
-
- END_SCROLL: MOV CUR_OFFSET,SI ;Update current offset.
- MOV SI,LINE
- CALL MOVE_BAR
- SCROLL_RETURN: RET
-
- ;--------------------------------------------------;
- ; This subroutine scrolls the bar if between start ;
- ; and end of page. Otherwise the page is scrolled. ;
- ;--------------------------------------------------;
-
- SCROLL_BAR: MOV SI,LINE ;Get current line.
- ADD SI,BP ;Add requested line.
- MOV BP,-DIR_RECORD ;Assume below beginning.
- CMP SI,PAGE_START ;Is it?
- JB SCROLL_PAGE ;If yes, scroll page instead.
- MOV BP,DIR_RECORD ;Do the same for end of page.
- CMP SI,PAGE_END
- JAE SCROLL_PAGE
- CALL MOVE_BAR
- RET
-
- SCROLL_PAGE: CALL SCROLL
- RET
-
- ;----------------------------------------------------;
- ; This subroutine does the actual moving of the bar. ;
- ;----------------------------------------------------;
-
- MOVE_BAR: MOV DI,BAR_START ;Remove old bar.
- MOV CX,BAR_LENGTH
- MOV BL,ATTR_TREE
- NEXT_BAR: CALL WRITE_SCREEN
- LOOP NEXT_BAR
-
- MOV LINE,SI ;And move bar to new line.
- MOV BL,BAR_ATTRIBUTE
- CALL GET_NAME
- MOV SI,CUR_RECORD ;Retrieve current record.
- MOV DI,LINE ;Retrieve line.
- MOV BAR_LENGTH,0 ;Zero out bar length counter.
- START_BAR: LODSB
- CMP AL,'\' ;Is it the root?
- JZ SAVE_START ;If yes, done here.
- INC DI ;Increment bar pointer
- INC DI ; past character as well.
- CMP AL,196 ;Is it horizontal bar character?
- JNZ START_BAR ;If no, find it.
- INC SI ;Bump point to start of name.
-
- SAVE_START: MOV BAR_START,DI ;Save.
- DISPLAY_BAR: INC BAR_LENGTH ;Increment bar length counter.
- MOV CX,1
- CALL WRITE_SCREEN ;Write the attribute.
- LODSB
- CMP AL,0 ;Are we at end of name?
- JNZ DISPLAY_BAR ;Continue until done.
- RET
-
- ;-------------------------------------------------;
- ; This subroutine displays the directory listing. ;
- ;-------------------------------------------------;
-
- UPDATE_SCREEN: XOR BP,BP
- MOV SI,CUR_OFFSET ;Retrieve starting offset.
- MOV DI,2*160+2 ;Point to row two of screen.
- MOV BH,21 ;21 lines to write.
- NEXT_WRITE: MOV CX,40 ;40 characters per line.
- NEXT_CHAR: LODSB ;Get a byte.
- MOV BL,AL ;Save it in BL.
- CALL WRITE_SCREEN ;Write them.
- ;----------------------FW--------------------------------------
- MOV AX,BAR_START
- CMP DI,AX ;FIND HIGHLIGH
- JB MOVE_ATTR ; ITEM
- ADD AX,BAR_LENGTH ; AND
- ADD AX,BAR_LENGTH ; LEAVE
- CMP DI,AX ; IT
- JB NOATTR ; ALONE
- MOVE_ATTR: MOV BL,ATTR_TREE ;ELSE USE TREE ATTR
- DEC DI
- CALL WRITE_SCREEN
- DEC DI
- NOATTR:
- ;--------------------------------------------------------------
- LOOP NEXT_CHAR
- ADD DI,80 ;Bump pointer to next line.
- DEC BH ;Do all 21 lines.
- JNZ NEXT_WRITE
- RET
-
- ;------------------------------------------------------------;
- ; This subroutine displays the directory by writing directly ;
- ; to the screen buffer. To avoid screen noise (snow) on the ;
- ; color card, the horizontal retrace has to be monitored. ;
- ;------------------------------------------------------------;
-
- WRITE_SCREEN: MOV DX,STATUS_REG ;Retrieve status register.
- MOV AX,VIDEO_SEG ;Point to screen segment.
- MOV ES,AX
-
- HORZ_RET: IN AL,DX ;Get status.
- TEST AL,1 ;Is it low?
- JNZ HORZ_RET ;If not, wait until it is.
- CLI ;No more interrupts.
-
- WAITS: IN AL,DX ;Get status.
- TEST AL,1 ;Is it high?
- JZ WAITS ;If no, wait until it is.
- MOV AL,BL ;Retrieve character; now it's OK
- STOSB ; to write to screen buffer.
- STI ;Interrupts back on.
- INC DI ;Bump pointer past attribute.
- PUSH CS
- POP ES
- RET ;Return
-
- ;-----------------------------------------------------------------------;
- ; These two subroutine clear either the messages or the entire screen. ;
- ;-----------------------------------------------------------------------;
-
- CLS: XOR CX,CX
- MOV DX,184FH ;Entire screen.
- CALL CLEAR_WINDOW
-
- CLEAR_MSG: CALL CURSOR_OFF
- MOV CX,1529H ;Row 22; column 41.
- MOV DX,184FH ;Row 24; column 79.
- PUSH BP
- PUSH BX
- MOV BH,ATTR_MSGS ;Clear MSGS AREA
- JMP SHORT CLEAR_WINDOW2
-
- CLEAR_LINE: MOV CX,1729H ;Row 23; column 41.
- MOV DX,174FH ;Row 23; column 79.
- JMP SHORT CLEAR_WINDOW
-
- CLEAR_WINDOW: PUSH BP
- PUSH BX
- MOV BH,ATTR_TEXT ;Clear with TEXT attribute.
- CLEAR_WINDOW2: MOV AX,600H
- INT 10H
- POP BX
- POP BP
- RET
-
- ;-----------------------------------------;
- ; These subroutines display the messages. ;
- ;-----------------------------------------;
-
- DISPLAY_TEXT: CALL SET_CURSOR ;Move cursor.
- GET_TEXT: LODSB
- CMP AL,0 ;Zero marks end of string.
- JZ END_TEXT
- ;--------------------FW----------------------------------------
- MOV BL,ATTR_TEXT
- ;--------------------------------------------------------------
- CALL WRITE_TEXT
- JMP SHORT GET_TEXT
- END_TEXT: RET
-
- WRITE_TEXT: PUSH SI ;BIOS does not save SI.
- MOV AH,0EH ;Write teletype.
- INT 10H
- POP SI
- RET
-
- ;---------------------------------------------------------;
- ; These four subroutines move the cursor, get the current ;
- ; directory, beep the speaker or get a keystroke. ;
- ;---------------------------------------------------------;
-
- SET_CURSOR: PUSH SI
- XOR BH,BH ;Page zero.
- MOV AH,2 ;Set cursor.
- INT 10H
- POP SI
- RET
-
- BEEP: MOV DL,7 ;Beep via DOS.
- MOV AH,2
- INT 21H
- RET
-
- READ_KEY: MOV AH,0 ;Retrieve keystroke via BIOS.
- INT 16H
- RET
-
- ;-----------------------------------------------;
- ; These subroutines turn the cursor off and on. ;
- ;-----------------------------------------------;
-
- CURSOR_OFF:
- MOV CX,2000H
- JMP SHORT SET_TYPE
-
- CURSOR_ON: MOV CX,CURSOR_TYPE
-
- SET_TYPE: MOV AH,1
- INT 10H
- RET
-
- ;----------------------------------------------;
- ; This subroutine displays the count of files. ;
- ;----------------------------------------------;
-
- COUNT_DIRS: MOV DX,1802H ;Row 24; column 2.
- CALL SET_CURSOR
- MOV AX,DIR_COUNT
- CALL GET_DIR_COUNT
- MOV SI,OFFSET DIR_MSG ;Display directory count.
- CALL GET_TEXT
- RET
-
- ;------------------------------------------;
- ; This subroutine converts hex to decimal. ;
- ;------------------------------------------;
-
- GET_COUNT: MOV AX,COUNT
- GET_DIR_COUNT: MOV BX,10 ;Convert to decimal.
- XOR CX,CX ;Zero in counter.
- NEXT_COUNT: XOR DX,DX
- DIV BX
- ADD DL,'0' ;Convert to ASCII.
- PUSH DX ;Save results.
- INC CX ;Also increment count.
- CMP AX,0 ;Are we done?
- JNZ NEXT_COUNT
-
- NEXT_NUMBER: POP AX ;Retrieve numbers.
- CALL WRITE_TEXT ;And write them.
- LOOP NEXT_NUMBER
- RET
- ;------------------------------------------;
- ; This subroutine MOVES TEST FROM SI TO DI ;
- ;------------------------------------------;
-
- MOVE_TEXT: LODSB
- CMP AL,0 ;Zero marks end of string.
- JZ MOVE_TEXT_END
- STOSB
- JMP MOVE_TEXT
- MOVE_TEXT_END: RET
-
- ;---------------------------------------------;
- ; This subroutine restores the current drive. ;
- ;---------------------------------------------;
-
- RESTORE_DRIVE: PUSH DX
- MOV DL,DEFAULT_DRIVE
- MOV AH,0EH
- INT 21H
- POP DX
- RET
-
- ;------------------------------------;
-
- DTA_AREA DB 256 DUP (00)
- DISK_BLOCK LABEL WORD
- CURRENT_DIR EQU DISK_BLOCK+18
- LEVEL_ADDRESS EQU CURRENT_DIR+65
- DIRECTORIES EQU LEVEL_ADDRESS+100
- DATA_BUFFER EQU LEVEL_ADDRESS+100
- END_RESIDENT EQU DATA_BUFFER+(DATA_RECORD*500)
-
- CODE ENDS
- END START
-